about summary refs log tree commit diff
path: root/converter/other/fiasco
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/fiasco')
-rw-r--r--converter/other/fiasco/Makefile59
-rw-r--r--converter/other/fiasco/README.netpbm41
-rw-r--r--converter/other/fiasco/binerror.c143
-rw-r--r--converter/other/fiasco/binerror.h50
-rw-r--r--converter/other/fiasco/buttons.c510
-rw-r--r--converter/other/fiasco/buttons.h50
-rw-r--r--converter/other/fiasco/codec/Makefile27
-rw-r--r--converter/other/fiasco/codec/approx.c702
-rw-r--r--converter/other/fiasco/codec/approx.h30
-rw-r--r--converter/other/fiasco/codec/bintree.c94
-rw-r--r--converter/other/fiasco/codec/bintree.h43
-rw-r--r--converter/other/fiasco/codec/coder.c965
-rw-r--r--converter/other/fiasco/codec/coder.h24
-rw-r--r--converter/other/fiasco/codec/coeff.c369
-rw-r--r--converter/other/fiasco/codec/coeff.h61
-rw-r--r--converter/other/fiasco/codec/control.c276
-rw-r--r--converter/other/fiasco/codec/control.h33
-rw-r--r--converter/other/fiasco/codec/cwfa.h107
-rw-r--r--converter/other/fiasco/codec/decoder.c1532
-rw-r--r--converter/other/fiasco/codec/decoder.h70
-rw-r--r--converter/other/fiasco/codec/dfiasco.c398
-rw-r--r--converter/other/fiasco/codec/dfiasco.h38
-rw-r--r--converter/other/fiasco/codec/domain-pool.c986
-rw-r--r--converter/other/fiasco/codec/domain-pool.h75
-rw-r--r--converter/other/fiasco/codec/ip.c324
-rw-r--r--converter/other/fiasco/codec/ip.h37
-rw-r--r--converter/other/fiasco/codec/motion.c338
-rw-r--r--converter/other/fiasco/codec/motion.h35
-rw-r--r--converter/other/fiasco/codec/mwfa.c864
-rw-r--r--converter/other/fiasco/codec/mwfa.h44
-rw-r--r--converter/other/fiasco/codec/options.c894
-rw-r--r--converter/other/fiasco/codec/options.h80
-rw-r--r--converter/other/fiasco/codec/prediction.c629
-rw-r--r--converter/other/fiasco/codec/prediction.h36
-rw-r--r--converter/other/fiasco/codec/subdivide.c650
-rw-r--r--converter/other/fiasco/codec/subdivide.h33
-rw-r--r--converter/other/fiasco/codec/tiling.c239
-rw-r--r--converter/other/fiasco/codec/tiling.h40
-rw-r--r--converter/other/fiasco/codec/wfa.h141
-rw-r--r--converter/other/fiasco/codec/wfalib.c774
-rw-r--r--converter/other/fiasco/codec/wfalib.h66
-rw-r--r--converter/other/fiasco/config.h96
-rw-r--r--converter/other/fiasco/display.c422
-rw-r--r--converter/other/fiasco/display.h49
-rw-r--r--converter/other/fiasco/doc/README.LIB51
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_delete.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_new.3432
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_basisfile.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_chroma_quality.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_comment.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_frame_pattern.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_optimizations.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_prediction.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_progress_meter.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_quantization.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_smoothing.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_tiling.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_title.31
-rw-r--r--converter/other/fiasco/doc/fiasco_c_options_set_video_param.31
-rw-r--r--converter/other/fiasco/doc/fiasco_coder.3106
-rw-r--r--converter/other/fiasco/doc/fiasco_d_options.31
-rw-r--r--converter/other/fiasco/doc/fiasco_d_options_delete.31
-rw-r--r--converter/other/fiasco/doc/fiasco_d_options_new.3122
-rw-r--r--converter/other/fiasco/doc/fiasco_d_options_set_4_2_0_format.31
-rw-r--r--converter/other/fiasco/doc/fiasco_d_options_set_magnification.31
-rw-r--r--converter/other/fiasco/doc/fiasco_d_options_set_smoothing.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_delete.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_comment.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_frame.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_framerate.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_height.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_length.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_title.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_get_width.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_is_color.31
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_new.3194
-rw-r--r--converter/other/fiasco/doc/fiasco_decoder_write_frame.31
-rw-r--r--converter/other/fiasco/doc/fiasco_get_error_message.341
-rw-r--r--converter/other/fiasco/doc/fiasco_get_verbosity.31
-rw-r--r--converter/other/fiasco/doc/fiasco_image.31
-rw-r--r--converter/other/fiasco/doc/fiasco_image_delete.31
-rw-r--r--converter/other/fiasco/doc/fiasco_image_get_height.31
-rw-r--r--converter/other/fiasco/doc/fiasco_image_get_width.31
-rw-r--r--converter/other/fiasco/doc/fiasco_image_is_color.31
-rw-r--r--converter/other/fiasco/doc/fiasco_image_new.395
-rw-r--r--converter/other/fiasco/doc/fiasco_options.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_delete.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_new.3441
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_4_2_0_format.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_basisfile.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_chroma_quality.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_frame_pattern.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_magnification.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_optimizations.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_prediction.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_progress_meter.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_quantization.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_smoothing.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_tiling.31
-rw-r--r--converter/other/fiasco/doc/fiasco_options_set_video_param.31
-rw-r--r--converter/other/fiasco/doc/fiasco_renderer.31
-rw-r--r--converter/other/fiasco/doc/fiasco_renderer_delete.31
-rw-r--r--converter/other/fiasco/doc/fiasco_renderer_new.3125
-rw-r--r--converter/other/fiasco/doc/fiasco_renderer_render.31
-rw-r--r--converter/other/fiasco/doc/fiasco_set_verbosity.346
-rw-r--r--converter/other/fiasco/fiasco.h425
-rw-r--r--converter/other/fiasco/fiascotopnm.c477
-rw-r--r--converter/other/fiasco/getopt.c1002
-rw-r--r--converter/other/fiasco/getopt.h129
-rw-r--r--converter/other/fiasco/getopt1.c189
-rw-r--r--converter/other/fiasco/input/Makefile26
-rw-r--r--converter/other/fiasco/input/basis.c141
-rw-r--r--converter/other/fiasco/input/basis.h26
-rw-r--r--converter/other/fiasco/input/matrices.c644
-rw-r--r--converter/other/fiasco/input/matrices.h27
-rw-r--r--converter/other/fiasco/input/mc.c334
-rw-r--r--converter/other/fiasco/input/mc.h28
-rw-r--r--converter/other/fiasco/input/nd.c237
-rw-r--r--converter/other/fiasco/input/nd.h28
-rw-r--r--converter/other/fiasco/input/read.c499
-rw-r--r--converter/other/fiasco/input/read.h31
-rw-r--r--converter/other/fiasco/input/tree.c303
-rw-r--r--converter/other/fiasco/input/tree.h28
-rw-r--r--converter/other/fiasco/input/weights.c200
-rw-r--r--converter/other/fiasco/input/weights.h27
-rw-r--r--converter/other/fiasco/lib/Makefile33
-rw-r--r--converter/other/fiasco/lib/arith.c708
-rw-r--r--converter/other/fiasco/lib/arith.h122
-rw-r--r--converter/other/fiasco/lib/bit-io.c327
-rw-r--r--converter/other/fiasco/lib/bit-io.h58
-rw-r--r--converter/other/fiasco/lib/dither.c1892
-rw-r--r--converter/other/fiasco/lib/dither.h27
-rw-r--r--converter/other/fiasco/lib/error.c326
-rw-r--r--converter/other/fiasco/lib/error.h39
-rw-r--r--converter/other/fiasco/lib/image.c512
-rw-r--r--converter/other/fiasco/lib/image.h59
-rw-r--r--converter/other/fiasco/lib/list.c258
-rw-r--r--converter/other/fiasco/lib/list.h72
-rw-r--r--converter/other/fiasco/lib/macros.h70
-rw-r--r--converter/other/fiasco/lib/misc.c563
-rw-r--r--converter/other/fiasco/lib/misc.h98
-rw-r--r--converter/other/fiasco/lib/mvcode.c14
-rw-r--r--converter/other/fiasco/lib/mvcode.h6
-rw-r--r--converter/other/fiasco/lib/rpf.c223
-rw-r--r--converter/other/fiasco/lib/rpf.h47
-rw-r--r--converter/other/fiasco/lib/types.h38
-rw-r--r--converter/other/fiasco/output/Makefile26
-rw-r--r--converter/other/fiasco/output/matrices.c547
-rw-r--r--converter/other/fiasco/output/matrices.h28
-rw-r--r--converter/other/fiasco/output/mc.c250
-rw-r--r--converter/other/fiasco/output/mc.h28
-rw-r--r--converter/other/fiasco/output/nd.c244
-rw-r--r--converter/other/fiasco/output/nd.h27
-rw-r--r--converter/other/fiasco/output/tree.c176
-rw-r--r--converter/other/fiasco/output/tree.h27
-rw-r--r--converter/other/fiasco/output/weights.c200
-rw-r--r--converter/other/fiasco/output/weights.h27
-rw-r--r--converter/other/fiasco/output/write.c250
-rw-r--r--converter/other/fiasco/output/write.h28
-rw-r--r--converter/other/fiasco/params.c727
-rw-r--r--converter/other/fiasco/params.h61
-rw-r--r--converter/other/fiasco/pnmtofiasco.c411
-rw-r--r--converter/other/fiasco/system.fiascorc120
165 files changed, 27650 insertions, 0 deletions
diff --git a/converter/other/fiasco/Makefile b/converter/other/fiasco/Makefile
new file mode 100644
index 00000000..0dd945ed
--- /dev/null
+++ b/converter/other/fiasco/Makefile
@@ -0,0 +1,59 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/../../..
+  BUILDDIR = $(SRCDIR)
+endif
+SUBDIR = converter/other/fiasco
+VPATH=.:$(SRCDIR)/$(SUBDIR)
+
+include $(BUILDDIR)/Makefile.config
+
+INCLUDES = \
+	-I$(SRCDIR)/$(SUBDIR)/codec -I$(SRCDIR)/$(SUBDIR)/input \
+	-I$(SRCDIR)/$(SUBDIR)/output -I$(SRCDIR)/$(SUBDIR)/lib \
+
+BINARIES = pnmtofiasco fiascotopnm
+
+MERGEBINARIES = $(BINARIES)
+
+SCRIPTS =
+
+all: $(BINARIES)
+
+FIASCOLIBS = codec/libfiasco_codec.a \
+	     input/libfiasco_input.a \
+	     output/libfiasco_output.a \
+	     lib/libfiasco_lib.a 
+
+COMMON_OBJECTS = binerror.o getopt.o getopt1.o params.o
+
+OBJECTS = $(BINARIES:%=%.o) $(COMMON_OBJECTS)
+
+MERGE_OBJECTS = $(BINARIES:%=%.o2) $(COMMON_OBJECTS)  $(FIASCOLIBS)
+
+SUBDIRS = codec input output lib
+
+include $(SRCDIR)/Makefile.common
+
+$(BINARIES):%:%.o $(COMMON_OBJECTS) $(FIASCOLIBS) $(NETPBMLIB) \
+   $(LIBOPT)
+	$(LD) $(LDFLAGS) -o $@ $< $(COMMON_OBJECTS) \
+	$(shell $(LIBOPT) $(FIASCOLIBS) $(NETPBMLIB)) $(MATHLIB) $(LDLIBS) \
+	$(RPATH) $(LADD)
+
+codec/libfiasco_codec.a: $(BUILDDIR)/$(SUBDIR)/codec FORCE
+	$(MAKE) -C codec -f $(SRCDIR)/$(SUBDIR)/codec/Makefile \
+		libfiasco_codec.a SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR)
+
+input/libfiasco_input.a: $(BUILDDIR)/$(SUBDIR)/input FORCE
+	$(MAKE) -C input -f $(SRCDIR)/$(SUBDIR)/input/Makefile \
+		libfiasco_input.a SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR)
+
+output/libfiasco_output.a: $(BUILDDIR)/$(SUBDIR)/output FORCE
+	$(MAKE) -C output -f $(SRCDIR)/$(SUBDIR)/output/Makefile \
+		libfiasco_output.a SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR)
+
+lib/libfiasco_lib.a: $(BUILDDIR)/$(SUBDIR)/lib FORCE
+	$(MAKE) -C lib -f $(SRCDIR)/$(SUBDIR)/lib/Makefile \
+		libfiasco_lib.a SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR)
+
+
diff --git a/converter/other/fiasco/README.netpbm b/converter/other/fiasco/README.netpbm
new file mode 100644
index 00000000..4f4019ad
--- /dev/null
+++ b/converter/other/fiasco/README.netpbm
@@ -0,0 +1,41 @@
+The 'fiasco' subdirectory of the Netpbm source tree is primarily a copy
+of the source distribution of the Fiasco package by Ullrich Hafner.
+Bryan Henderson adapted fiasco-1.0 on July 6, 2000 to netpbm, and then
+merged in all the updates from fiasco-1.3 on February 9, 2001.
+
+The changes are:
+
+- Uses Netpbm libraries for input and output of Netpbm format images.
+
+- Works with maxvals other than 255 in Netpbm input images.  This change
+  also makes a minor correction to the maxval 255 case.  Where the Fiasco
+  package multiplies by 16 to convert from 8 bit to 12 bit intensity,
+  the correct factor is 4095/255.
+
+- Does not issue warning when system configuration file not found.
+  The location of that file is a compile-time option in 'fiasco', but
+  fixed at /etc in Netpbm.  The expectation is that Netpbm users will
+  never have a system configuration file.
+
+- Does not fail if basis file small.fco is not found.  The Fiasco code
+  already contained facilities for defaulting to a built-in version of
+  small.fco, but it was disabled by an early check for existence of
+  the basis file as an actual file.  In Netpbm, that check for
+  existence is simply removed.
+
+- Remove WINDOWS config.h configuration macro, which determined whether
+  files would be open with "b" flag (binary).  Use "b" flag unconditionally.
+
+- Rename internal "log2" function to "Log2" to avoid conflict with existing
+  "log2" macro or function.  The original package has conditional compilation
+  to allow it to use the existing log2 when configured for a system that has
+  it.  In Netpbm, we always use the private version.
+
+- Compilation warnings fixed.
+
+- 'bin' subdirectory moved to top level directory.
+
+- man pages for programs moved from doc subdirectory to top level directory.
+
+- man page of pnmpsnr created.
+
diff --git a/converter/other/fiasco/binerror.c b/converter/other/fiasco/binerror.c
new file mode 100644
index 00000000..8a41a214
--- /dev/null
+++ b/converter/other/fiasco/binerror.c
@@ -0,0 +1,143 @@
+/*
+ *  error.c:		Error handling
+ *
+ *  Written by:		Stefan Frank
+ *			Ullrich Hafner
+ *  
+ *  Credits:	Modelled after variable argument routines from Jef
+ *		Poskanzer's pbmplus package. 
+ *
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/03/20 21:29:59 $
+ *  $Author: hafner $
+ *  $Revision: 4.3 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+#define _ERROR_C
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#if STDC_HEADERS
+#	include <stdarg.h>
+#	define VA_START(args, lastarg) va_start(args, lastarg)
+#else  /* not STDC_HEADERS */
+#	include <varargs.h>
+#	define VA_START(args, lastarg) va_start(args)
+#endif /* not STDC_HEADERS */
+#include <string.h>
+
+#if HAVE_SETJMP_H
+#	include <setjmp.h>
+#endif /* HAVE_SETJMP_H */
+
+#include "fiasco.h"
+#include "binerror.h"
+
+/*****************************************************************************
+
+			     global variables
+  
+*****************************************************************************/
+
+int   error_line = 0;
+const char *error_file = NULL;
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+static const char *executable = "(name not initialized)";
+
+/*****************************************************************************
+
+			       public code
+  
+*****************************************************************************/
+
+void
+init_error_handling (const char *name)
+/*
+ *  Initialize filename of executable.
+ *
+ *  No return value.
+ */
+{
+   if (name)
+      executable = strdup (name);
+}
+
+void
+_error (const char *format, ...)
+/*
+ *  Print error message and exit.
+ *
+ *  No return value.
+ */
+{
+   va_list	args;
+
+   VA_START (args, format);
+
+   fprintf (stderr, "%s: %s: line %d:\nError: ",
+	    executable, error_file, error_line);
+#if HAVE_VPRINTF
+   vfprintf (stderr, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+   fputc ('\n', stderr);
+   va_end(args);
+
+   exit (1);
+}
+
+void
+_file_error (const char *filename)
+/*
+ *  Print file error message and exit.
+ *
+ *  No return value.
+ */
+{
+   fprintf (stderr, "%s: %s: line %d:\nError: ",
+	    executable, error_file, error_line);
+   perror (filename);
+
+   exit (2);
+}
+
+void 
+_warning (const char *format, ...)
+/*
+ *  Issue a warning and continue execution.
+ *
+ *  No return value.
+ */
+{
+   va_list args;
+
+   VA_START (args, format);
+
+   fprintf (stderr, "%s: %s: line %d:\nWarning: ",
+	    executable, error_file, error_line);
+#if HAVE_VPRINTF
+   vfprintf (stderr, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+   fputc ('\n', stderr);
+
+   va_end (args);
+}
diff --git a/converter/other/fiasco/binerror.h b/converter/other/fiasco/binerror.h
new file mode 100644
index 00000000..e7ff43c9
--- /dev/null
+++ b/converter/other/fiasco/binerror.h
@@ -0,0 +1,50 @@
+/*
+ *  error.h
+ *  
+ *  Written by:		Stefan Frank
+ *			Ullrich Hafner
+ *
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/03/20 21:29:59 $
+ *  $Author: hafner $
+ *  $Revision: 4.3 $
+ *  $State: Exp $
+ */
+
+#ifndef _ERROR_H
+#define _ERROR_H
+
+#define error          error_line=__LINE__,error_file=__FILE__,_error
+#define warning        error_line=__LINE__,error_file=__FILE__,_warning
+#define file_error(fn) error_line=__LINE__,error_file=__FILE__,_file_error(fn)
+
+#ifdef _ERROR_C
+#define _EXTERN_TYPE
+#else
+#define _EXTERN_TYPE	extern
+#endif
+
+_EXTERN_TYPE int   error_line;
+_EXTERN_TYPE const char *error_file;
+
+void
+init_error_handling (const char *name);
+void
+_error (const char *format, ...);
+void
+_warning (const char *format, ...);
+void
+_file_error (const char *filename);
+
+#if HAVE_ASSERT_H
+#	include <assert.h>
+#else /* not HAVE_ASSERT_H */
+#	define assert(exp)	{if (!(exp)) error ("Assertion `" #exp " != NULL' failed.");}
+#endif /* not HAVE_ASSERT_H */
+
+#endif /* not _ERROR_H */
+
diff --git a/converter/other/fiasco/buttons.c b/converter/other/fiasco/buttons.c
new file mode 100644
index 00000000..82ed18cd
--- /dev/null
+++ b/converter/other/fiasco/buttons.c
@@ -0,0 +1,510 @@
+/*
+ *  buttons.c:		Draw MWFA player buttons in X11 window	
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/15 17:23:11 $
+ *  $Author: hafner $
+ *  $Revision: 5.2 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#ifndef X_DISPLAY_MISSING
+
+#include <X11/Xlib.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include "types.h"
+#include "macros.h"
+
+#include "display.h"
+#include "binerror.h"
+#include "buttons.h"
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+static const int EVENT_MASK = (KeyPressMask | ButtonPressMask |
+			       ButtonReleaseMask | ExposureMask);
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+draw_progress_bar (x11_info_t *xinfo, binfo_t *binfo, unsigned n,
+		   unsigned n_frames);
+static void
+draw_button (x11_info_t *xinfo, binfo_t *binfo,
+	     buttons_t button, bool_t pressed);
+static void
+draw_control_panel (x11_info_t *xinfo, binfo_t *binfo,
+		    unsigned n, unsigned n_frames);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+binfo_t * 
+init_buttons (x11_info_t *xinfo, unsigned n, unsigned n_frames,
+	      unsigned buttons_height, unsigned progbar_height)
+/*
+ *  Initialize a toolbar with the typical collection of video player
+ *  buttons (pause, play, record, next, etc.) in the window given by 'xinfo'.
+ *  'n' gives the current frame, 'whereas' n_frames is the total number of
+ *  frames of the video stream.
+ *  The size of the button toolbar is given by 'buttons_height',
+ *  the size of the progressbar is given by 'progbar_height'.
+ *
+ *  Return value:
+ *	struct managing the toolbar and progressbar information
+ */
+{
+   XGCValues  values;
+   XEvent     event;
+   Colormap   cmap;
+   XColor     gray, dgray, lgray, red;
+   XColor     graye, dgraye, lgraye, rede;
+   buttons_t  button;			/* counter */
+   binfo_t   *binfo = calloc (1, sizeof (binfo_t));
+
+   if (!binfo)
+      error ("Out of memory.");
+   
+   binfo->width            = xinfo->ximage->width;
+   binfo->height           = buttons_height;
+   binfo->progbar_height   = progbar_height;
+   binfo->record_is_rewind = NO;
+
+   /*
+    *  Generate sub-window for control panel
+    */
+   binfo->window = XCreateSimpleWindow (xinfo->display, xinfo->window,
+					0, xinfo->ximage->height,
+					binfo->width, binfo->height, 0,
+					BlackPixel (xinfo->display,
+						    xinfo->screen),
+					WhitePixel (xinfo->display,
+						    xinfo->screen));
+   XSelectInput(xinfo->display, binfo->window, StructureNotifyMask);
+   XMapWindow (xinfo->display, binfo->window);
+   do
+   {
+      XNextEvent (xinfo->display, &event);
+   }
+   while (event.type != MapNotify || event.xmap.event != binfo->window);
+   XSelectInput (xinfo->display, binfo->window, EVENT_MASK);
+
+   /*
+    *  Generate graphic contexts for different colors.
+    */
+   cmap = DefaultColormap (xinfo->display, xinfo->screen);
+   XAllocNamedColor (xinfo->display, cmap, "#404040", &dgray, &dgraye);
+   XAllocNamedColor (xinfo->display, cmap, "white", &lgray, &lgraye);
+   XAllocNamedColor (xinfo->display, cmap, "#a8a8a8", &gray, &graye);
+   XAllocNamedColor (xinfo->display, cmap, "red", &red, &rede);
+   
+   values.foreground = BlackPixel (xinfo->display, xinfo->screen);
+   values.background = WhitePixel (xinfo->display, xinfo->screen);
+   binfo->gc [BLACK] = XCreateGC (xinfo->display,
+				  RootWindow (xinfo->display, xinfo->screen),
+				  (GCForeground | GCBackground), &values);
+   values.foreground = BlackPixel (xinfo->display, xinfo->screen);
+   values.background = WhitePixel (xinfo->display, xinfo->screen);
+   values.line_width = 3;
+   values.join_style = JoinRound;
+   binfo->gc [THICKBLACK] = XCreateGC (xinfo->display,
+				       RootWindow (xinfo->display,
+						   xinfo->screen),
+				       (GCForeground | GCBackground
+					| GCLineWidth | GCJoinStyle), &values);
+   values.foreground = gray.pixel;
+   values.background = WhitePixel (xinfo->display, xinfo->screen);
+   binfo->gc [NGRAY] = XCreateGC (xinfo->display,
+				  RootWindow (xinfo->display, xinfo->screen),
+				  (GCForeground | GCBackground), &values);
+   values.foreground = lgray.pixel;
+   values.background = WhitePixel (xinfo->display, xinfo->screen);
+   binfo->gc [LGRAY] = XCreateGC (xinfo->display,
+				  RootWindow (xinfo->display, xinfo->screen),
+				  (GCForeground | GCBackground), &values);
+   values.foreground = dgray.pixel;
+   values.background = WhitePixel (xinfo->display, xinfo->screen);
+   binfo->gc [DGRAY] = XCreateGC (xinfo->display,
+				  RootWindow (xinfo->display, xinfo->screen),
+				  (GCForeground | GCBackground), &values);
+   values.foreground = red.pixel;
+   values.background = WhitePixel (xinfo->display, xinfo->screen);
+   binfo->gc [RED]   = XCreateGC (xinfo->display,
+				  RootWindow (xinfo->display, xinfo->screen),
+				  (GCForeground | GCBackground), &values);
+
+   for (button = 0; button < NO_BUTTON; button++)
+      binfo->pressed [button] = NO;
+
+   draw_control_panel (xinfo, binfo, n, n_frames); 
+   
+   return binfo;
+}
+
+void
+wait_for_input (x11_info_t *xinfo)
+/*
+ *  Wait for key press or mouse click in window 'xinfo'.
+ *  Redraw 'image' if event other then ButtonPress or KeyPress occurs.
+ *  Enlarge or reduce size of image by factor 2^'enlarge_factor'.
+ *
+ *  No return value.
+ *
+ *  Side effect:
+ *	program is terminated after key press or mouse click.
+ */
+{
+   bool_t leave_loop = NO;
+   
+   XSelectInput (xinfo->display, xinfo->window, EVENT_MASK);
+
+   while (!leave_loop)
+   {
+      XEvent event;
+
+      XMaskEvent (xinfo->display, EVENT_MASK, &event);
+      switch (event.type)
+      {
+	 case ButtonPress:
+	 case KeyPress:
+	    leave_loop = YES;
+	    break;
+	 default:
+	    display_image (0, 0, xinfo);
+	    break;
+      }
+   }
+}
+
+void
+check_events (x11_info_t *xinfo, binfo_t *binfo, unsigned n, unsigned n_frames)
+/*
+ *  Check the X11 event loop. If the PAUSE buttonin the of panel 'binfo'
+ *  is activated wait until next event occurs.
+ *  Redraw 'image' if event other then ButtonPress or ButtonRelease occurs.
+ *  Enlarge or reduce size of image by factor 2^'enlarge_factor'.
+ *  'n' gives the current frame, 'whereas' n_frames is the total number of
+ *  frames of the video stream.
+ *
+ *  No return values.
+ *
+ *  Side effects:
+ *	status of buttons (binfo->pressed [button]) is changed accordingly.
+ */
+{
+   bool_t leave_eventloop;
+
+   leave_eventloop = (!binfo->pressed [PAUSE_BUTTON]
+		      && binfo->pressed [PLAY_BUTTON])
+		     || (!binfo->pressed [PAUSE_BUTTON]
+			 && binfo->record_is_rewind
+			 && binfo->pressed [RECORD_BUTTON])
+		     || binfo->pressed [RECORD_BUTTON];
+   draw_progress_bar (xinfo, binfo, n, n_frames);
+
+   if (binfo->pressed [PAUSE_BUTTON] && binfo->pressed [PLAY_BUTTON])
+   {
+      XFlush (xinfo->display);
+      draw_button (xinfo, binfo, PLAY_BUTTON, NO); /* clear PLAY mode */
+      XFlush (xinfo->display);
+   }
+   if (binfo->pressed [PAUSE_BUTTON]
+       && binfo->record_is_rewind && binfo->pressed [RECORD_BUTTON])
+   {
+      XFlush (xinfo->display);
+      draw_button (xinfo, binfo, RECORD_BUTTON, NO); /* clear PLAY mode */
+      XFlush (xinfo->display);
+   }
+
+   if (binfo->pressed [STOP_BUTTON])
+   {
+      XFlush (xinfo->display);
+      draw_button (xinfo, binfo, STOP_BUTTON, NO); /* clear STOP button */
+      XFlush (xinfo->display);
+   }
+
+   do
+   {
+      XEvent event;
+      int    button;
+      bool_t wait_release = NO;
+	 
+      
+      if (XCheckMaskEvent (xinfo->display, EVENT_MASK, &event))
+      {
+	 switch (event.type)
+	 {
+	    case ButtonPress:
+	       wait_release = NO;
+	       if (!(binfo->pressed [RECORD_BUTTON] &&
+		     !binfo->record_is_rewind))
+		  for (button = 0; button < NO_BUTTON; button++)
+		  {
+		     int x0, y0, x1, y1; /* button coordinates */
+		  
+		     x0 = button * (binfo->width / NO_BUTTON);
+		     y0 = binfo->progbar_height;
+		     x1 = x0 + binfo->width / NO_BUTTON;
+		     y1 = y0 + binfo->height - binfo->progbar_height - 1;
+		     if (event.xbutton.x > x0 && event.xbutton.x < x1
+			 && event.xbutton.y > y0 && event.xbutton.y < y1) 
+		     {
+			draw_button (xinfo, binfo, button,
+				     !binfo->pressed [button]);
+			wait_release = YES;
+			break;
+		     }
+		  }
+	       break;
+	    case ButtonRelease:
+	       wait_release = NO;
+	       break;
+	    default:
+	       wait_release = NO;
+	       draw_control_panel (xinfo, binfo, n, n_frames);
+	       display_image (0, 0, xinfo);
+	       break;
+	 }
+	 leave_eventloop = !wait_release
+			   && (binfo->pressed [PLAY_BUTTON]
+			       || binfo->pressed [STOP_BUTTON]
+			       || binfo->pressed [RECORD_BUTTON]
+			       || binfo->pressed [QUIT_BUTTON]);
+      }
+   } while (!leave_eventloop);
+
+   if ((binfo->pressed [RECORD_BUTTON] && !binfo->record_is_rewind)
+       && n == n_frames - 1)
+   {
+      binfo->record_is_rewind = YES;
+      draw_button (xinfo, binfo, RECORD_BUTTON, NO);
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+draw_control_panel (x11_info_t *xinfo, binfo_t *binfo,
+		    unsigned n, unsigned n_frames)
+/*
+ *  Draw control panel 'binfo' with all buttons and progressbar in
+ *  the given 'window'.
+ *  'n' gives the current frame, 'whereas' n_frames is the total number of
+ *  frames of the video stream.
+ *
+ *  No return value.
+ */
+{
+   buttons_t button;
+   
+   XFillRectangle (xinfo->display, binfo->window, binfo->gc [NGRAY],
+		   0, 0, binfo->width, binfo->height);
+   draw_progress_bar (xinfo, binfo, n, n_frames);
+   for (button = 0; button < NO_BUTTON; button++)
+      draw_button (xinfo, binfo, button, binfo->pressed [button]);
+}
+
+static void
+draw_progress_bar (x11_info_t *xinfo, binfo_t *binfo, unsigned n,
+		   unsigned n_frames)
+/*
+ *  Draw progressbar of control panel 'binfo' in the given 'window'.
+ *  'n' gives the current frame, whereas 'n_frames' is the total number of
+ *  frames of the video stream.
+ *
+ *  No return value.
+ */
+{
+   unsigned x, y, width, height;
+
+   x 	  = 2;
+   y 	  = 1;
+   width  = binfo->width - 5;
+   height = binfo->progbar_height - 3;
+   
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [DGRAY],
+	      x, y, x + width, y);
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [DGRAY],
+	      x, y, x, y + height - 1);
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [LGRAY],
+	      x + width, y + 1, x + width, y + height);
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [LGRAY],
+	      x, y + height, x + width, y + height);
+
+   x++; y++; width  -= 2; height -= 2;
+   XFillRectangle (xinfo->display, binfo->window, binfo->gc [NGRAY],
+		   x, y, width, height);
+
+   XFillRectangle (xinfo->display, binfo->window, binfo->gc [BLACK],
+		   x + n * max (1, width / n_frames), y,
+		   max (1, width / n_frames), height);
+}
+
+static void
+draw_button (x11_info_t *xinfo, binfo_t *binfo,
+	     buttons_t button, bool_t pressed)
+/*
+ *  Draw 'button' of control panel 'binfo' in the given 'window'.
+ *  'pressed' indicates whether the button is pressed or not.
+ *
+ *  No return value.
+ */
+{
+   grayscale_t top, bottom;		/* index of GC */
+   unsigned    x, y, width, height;	/* coordinates of button */
+   
+   x 	  = button * (binfo->width / NO_BUTTON);
+   y 	  = binfo->progbar_height;
+   width  = binfo->width / NO_BUTTON;
+   height = binfo->height - binfo->progbar_height - 1;
+   
+   if (width < 4 || height < 4)
+      return;
+   
+   if (pressed)
+   {
+      top    = DGRAY;
+      bottom = LGRAY;
+   }
+   else
+   {
+      top    = LGRAY;
+      bottom = DGRAY;
+   }
+
+   x 	 += 2;
+   width -= 4;
+   
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [top],
+	      x, y, x + width, y);
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [top],
+	      x, y, x, y + height - 1);
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [bottom],
+	      x + width, y + 1, x + width, y + height);
+   XDrawLine (xinfo->display, binfo->window, binfo->gc [bottom],
+	      x, y + height, x + width, y + height);
+
+   x++; y++; width  -= 2; height -= 2;
+   XFillRectangle (xinfo->display, binfo->window, binfo->gc [NGRAY],
+		   x, y, width, height);
+
+   switch (button)
+   {
+      case STOP_BUTTON:
+	 XFillRectangle (xinfo->display, binfo->window, binfo->gc [BLACK],
+			 x + width / 2 - 6, y + height / 2 - 4, 11, 11);
+	 if (pressed && !binfo->pressed [STOP_BUTTON])
+	 {
+	    draw_button (xinfo, binfo, PLAY_BUTTON, NO);
+	    draw_button (xinfo, binfo, PAUSE_BUTTON, NO); 
+	    draw_button (xinfo, binfo, RECORD_BUTTON, NO); 
+	 }
+	 break;
+      case PAUSE_BUTTON:
+	 XFillRectangle (xinfo->display, binfo->window, binfo->gc [BLACK],
+			 x + width / 2 - 6, y + height / 2 - 4, 5, 11);
+	 XFillRectangle (xinfo->display, binfo->window, binfo->gc [BLACK],
+			 x + width / 2 + 1, y + height / 2 - 4, 5, 11);
+	 break;
+      case PLAY_BUTTON:
+	 {
+	    XPoint triangle [3];
+
+	    triangle [0].x = x + width / 2 - 5;
+	    triangle [0].y = y + height / 2 - 5;
+	    triangle [1].x = 10;
+	    triangle [1].y = 6;
+	    triangle [2].x = -10;
+	    triangle [2].y = 6;
+
+	    XFillPolygon (xinfo->display, binfo->window, binfo->gc [BLACK],
+			  triangle, 3, Convex, CoordModePrevious);
+	    if (pressed && !binfo->pressed [PLAY_BUTTON]
+		&& binfo->pressed [RECORD_BUTTON])
+	       draw_button (xinfo, binfo, RECORD_BUTTON, NO);
+	 }
+	 break;
+      case RECORD_BUTTON:
+	 if (!binfo->record_is_rewind)
+	 {
+	    XFillArc (xinfo->display, binfo->window, binfo->gc [RED],
+		      x + width / 2 - 5, y + height / 2 - 5, 11, 11, 0,
+		      360 * 64);
+	    if (pressed && !binfo->pressed [RECORD_BUTTON])
+	    {
+	       draw_button (xinfo, binfo, STOP_BUTTON, YES);
+	       draw_button (xinfo, binfo, PLAY_BUTTON, NO);
+	       draw_button (xinfo, binfo, PAUSE_BUTTON, NO); 
+	    }
+	 }
+	 else
+	 {
+	    XPoint triangle [3];
+
+	    triangle [0].x = x + width / 2 + 5;
+	    triangle [0].y = y + height / 2 - 5;
+	    triangle [1].x = -10;
+	    triangle [1].y = 6;
+	    triangle [2].x = 10;
+	    triangle [2].y = 6;
+
+	    XFillPolygon (xinfo->display, binfo->window, binfo->gc [BLACK],
+			  triangle, 3, Convex, CoordModePrevious);
+	    if (pressed && !binfo->pressed [RECORD_BUTTON]
+		&& binfo->pressed [PLAY_BUTTON])
+	       draw_button (xinfo, binfo, PLAY_BUTTON, NO);
+	 }
+	 break;
+      case QUIT_BUTTON:
+	 {
+	    XPoint triangle [3];
+
+	    triangle [0].x = x + width / 2 - 6;
+	    triangle [0].y = y + height / 2 + 2;
+	    triangle [1].x = 6;
+	    triangle [1].y = -7;
+	    triangle [2].x = 6;
+	    triangle [2].y = 7;
+
+	    XFillPolygon (xinfo->display, binfo->window, binfo->gc [BLACK],
+			  triangle, 3, Convex, CoordModePrevious);
+	    XFillRectangle (xinfo->display, binfo->window, binfo->gc [BLACK],
+			    x + width / 2 - 5, y + height / 2 + 4, 11, 3);
+	 }
+	 break;
+      default:
+	 break;
+   }
+   binfo->pressed [button] = pressed;
+}
+
+#endif /* not X_DISPLAY_MISSING */
diff --git a/converter/other/fiasco/buttons.h b/converter/other/fiasco/buttons.h
new file mode 100644
index 00000000..a09f3423
--- /dev/null
+++ b/converter/other/fiasco/buttons.h
@@ -0,0 +1,50 @@
+/*
+ *  buttons.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:51:17 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _BUTTONS_H
+#define _BUTTONS_H
+
+#ifndef X_DISPLAY_MISSING
+
+typedef enum grayscale_e {BLACK, NGRAY, LGRAY, DGRAY, RED,
+			  THICKBLACK, NO_GC} grayscale_t;
+typedef enum buttons_e {STOP_BUTTON, PLAY_BUTTON, PAUSE_BUTTON, RECORD_BUTTON,
+			QUIT_BUTTON, NO_BUTTON} buttons_t;
+
+typedef struct buttoninfo
+{
+   Window   window;
+   bool_t   pressed [NO_BUTTON];
+   GC	    gc [NO_GC];
+   unsigned width;
+   unsigned height;
+   unsigned progbar_height;
+   bool_t   record_is_rewind;
+} binfo_t;
+
+void
+check_events (x11_info_t *xinfo, binfo_t *binfo, unsigned n,
+	      unsigned n_frames);
+void
+wait_for_input (x11_info_t *xinfo);
+binfo_t * 
+init_buttons (x11_info_t *xinfo, unsigned n, unsigned n_frames,
+	      unsigned buttons_height, unsigned progbar_height);
+
+#endif /* not X_DISPLAY_MISSING */
+
+#endif /* not _BUTTONS_H */
+
diff --git a/converter/other/fiasco/codec/Makefile b/converter/other/fiasco/codec/Makefile
new file mode 100644
index 00000000..9a9d502a
--- /dev/null
+++ b/converter/other/fiasco/codec/Makefile
@@ -0,0 +1,27 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/../../../..
+  BUILDDIR = $(SRCDIR)
+endif
+FIASCOSUBDIR = converter/other/fiasco
+SUBDIR = $(FIASCOSUBDIR)/codec
+VPATH=.:$(SRCDIR)/$(SUBDIR)
+
+include $(BUILDDIR)/Makefile.config
+
+INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR) -I$(SRCDIR)/$(FIASCOSUBDIR)/lib \
+	 -I$(SRCDIR)/$(FIASCOSUBDIR)/input -I$(SRCDIR)/$(FIASCOSUBDIR)/output 
+
+OBJECTS =  approx.o bintree.o coder.o coeff.o \
+           control.o decoder.o dfiasco.o domain-pool.o ip.o motion.o mwfa.o \
+           options.o prediction.o subdivide.o tiling.o wfalib.o
+
+MERGE_OBJECTS = $(OBJECTS)
+
+all: libfiasco_codec.a
+
+include $(SRCDIR)/Makefile.common
+
+libfiasco_codec.a: $(OBJECTS)
+	$(AR) -rc $@ $(OBJECTS)
+	$(RANLIB) $@
+
diff --git a/converter/other/fiasco/codec/approx.c b/converter/other/fiasco/codec/approx.c
new file mode 100644
index 00000000..72e38cbf
--- /dev/null
+++ b/converter/other/fiasco/codec/approx.c
@@ -0,0 +1,702 @@
+/*
+ *  approx.c:		Approximation of range images with matching pursuit
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include <math.h>
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "cwfa.h"
+#include "ip.h"
+#include "rpf.h"
+#include "domain-pool.h"
+#include "misc.h"
+#include "list.h"
+#include "approx.h"
+#include "coeff.h"
+#include "wfalib.h"
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+typedef struct mp
+{
+   word_t exclude [MAXEDGES];
+   word_t indices [MAXEDGES + 1];
+   word_t into [MAXEDGES + 1];
+   real_t weight [MAXEDGES];
+   real_t matrix_bits;
+   real_t weights_bits;
+   real_t err;
+   real_t costs;
+} mp_t;
+
+/*****************************************************************************
+
+			     prototypes
+  
+*****************************************************************************/
+
+static void
+orthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm,
+	       const word_t *domain_blocks, const coding_t *c);
+static void 
+matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
+		  unsigned max_edges, int y_state, const range_t *range,
+		  const domain_pool_t *domain_pool, const coeff_t *coeff,
+		  const wfa_t *wfa, const coding_t *c);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+real_t 
+approximate_range (real_t max_costs, real_t price, int max_edges,
+		   int y_state, range_t *range, domain_pool_t *domain_pool,
+		   coeff_t *coeff, const wfa_t *wfa, const coding_t *c)
+/*
+ *  Approximate image block 'range' by matching pursuit. This functions
+ *  calls the matching pursuit algorithm several times (with different
+ *  parameters) in order to find the best approximation. Refer to function
+ *  'matching_pursuit()' for more details about parameters.
+ *
+ *  Return value:
+ *	approximation costs
+ */
+{
+   mp_t	  mp;
+   bool_t success = NO;
+
+   /*
+    *  First approximation attempt: default matching pursuit algorithm.
+    */
+   mp.exclude [0] = NO_EDGE;
+   matching_pursuit (&mp, c->options.full_search, price, max_edges,
+		     y_state, range, domain_pool, coeff, wfa, c);
+
+   /*
+    *  Next approximation attempt: remove domain block mp->indices [0]
+    *  from domain pool (vector with smallest costs) and run the
+    *  matching pursuit again.
+    */
+   if (c->options.second_domain_block)
+   {
+      mp_t tmp_mp = mp;
+      
+      tmp_mp.exclude [0] = tmp_mp.indices [0];
+      tmp_mp.exclude [1] = NO_EDGE;
+	    
+      matching_pursuit (&tmp_mp, c->options.full_search, price, max_edges,
+			y_state, range, domain_pool, coeff, wfa, c);
+      if (tmp_mp.costs < mp.costs)	/* success */
+      {
+	 success = YES;
+	 mp      = tmp_mp;
+      }
+   }
+
+   /*
+    *  Next approximation attempt: check whether some coefficients have
+    *  been quantized to zero. Vectors causing the underflow are
+    *  removed from the domain pool and then the matching pursuit
+    *  algorithm is run again (until underflow doesn't occur anymore).
+    */
+   if (c->options.check_for_underflow)
+   {
+      int  iteration = -1;
+      mp_t tmp_mp    = mp;
+      
+      do
+      {
+	 int i;
+ 
+	 iteration++;
+	 tmp_mp.exclude [iteration] = NO_EDGE;
+	 
+	 for (i = 0; isdomain (tmp_mp.indices [i]); i++)
+	    if (tmp_mp.weight [i] == 0)
+	    {
+	       tmp_mp.exclude [iteration] = tmp_mp.indices [i];
+	       break;
+	    }
+      
+	 if (isdomain (tmp_mp.exclude [iteration])) /* try again */
+	 {
+	    tmp_mp.exclude [iteration + 1] = NO_EDGE;
+	    
+	    matching_pursuit (&tmp_mp, c->options.full_search, price,
+			      max_edges, y_state, range, domain_pool,
+			      coeff, wfa, c);
+	    if (tmp_mp.costs < mp.costs)	/* success */
+	    {
+	       success = YES;
+	       mp      = tmp_mp;
+	    }
+	 }
+      } while (isdomain (tmp_mp.exclude [iteration])
+	       && iteration < MAXEDGES - 1);
+   }
+
+   /*
+    *  Next approximation attempt: check whether some coefficients have
+    *  been quantized to +/- max-value. Vectors causing the overflow are
+    *  removed from the domain pool and then the matching pursuit
+    *  algorithm is run again (until overflow doesn't occur anymore).
+    */
+   if (c->options.check_for_overflow)
+   {
+      int  iteration = -1;
+      mp_t tmp_mp    = mp;
+      
+      do
+      {
+	 int i;
+ 
+	 iteration++;
+	 tmp_mp.exclude [iteration] = NO_EDGE;
+	 
+	 for (i = 0; isdomain (tmp_mp.indices [i]); i++)
+	 {
+	    rpf_t *rpf = tmp_mp.indices [i] ? coeff->rpf : coeff->dc_rpf;
+	    
+	    if (tmp_mp.weight [i] == btor (rtob (200, rpf), rpf)
+		|| tmp_mp.weight [i] == btor (rtob (-200, rpf), rpf))
+	    {
+	       tmp_mp.exclude [iteration] = tmp_mp.indices [i];
+	       break;
+	    }
+	 }
+      
+	 if (isdomain (tmp_mp.exclude [iteration])) /* try again */
+	 {
+	    tmp_mp.exclude [iteration + 1] = NO_EDGE;
+	    
+	    matching_pursuit (&tmp_mp, c->options.full_search, price,
+			      max_edges, y_state, range, domain_pool,
+			      coeff, wfa, c);
+	    if (tmp_mp.costs < mp.costs)	/* success */
+	    {
+	       success = YES;
+	       mp      = tmp_mp;
+	    }
+	 }
+      } while (isdomain (tmp_mp.exclude [iteration])
+	       && iteration < MAXEDGES - 1);
+   }
+
+   /*
+    *  Finally, check whether the best approximation has costs
+    *  smaller than 'max_costs'.
+    */
+   if (mp.costs < max_costs) 
+   {
+      int    edge;
+      bool_t overflow  = NO;
+      bool_t underflow = NO;
+      int    new_index, old_index;
+
+      new_index = 0;
+      for (old_index = 0; isdomain (mp.indices [old_index]); old_index++)
+	 if (mp.weight [old_index] != 0)
+	 {
+	    rpf_t *rpf = mp.indices [old_index] ? coeff->rpf : coeff->dc_rpf;
+	    
+	    if (mp.weight [old_index] == btor (rtob (200, rpf), rpf)
+		|| mp.weight [old_index] == btor (rtob (-200, rpf), rpf))
+	       overflow = YES;
+	    
+	    mp.indices [new_index] = mp.indices [old_index];
+	    mp.into [new_index]    = mp.into [old_index];
+	    mp.weight [new_index]  = mp.weight [old_index];
+	    new_index++;
+	 }
+	 else
+	    underflow = YES;
+      
+      mp.indices [new_index] = NO_EDGE;
+      mp.into  [new_index]   = NO_EDGE;
+
+      /*
+       *  Update of probability models
+       */
+      {
+	 word_t *domain_blocks = domain_pool->generate (range->level, y_state,
+							wfa,
+							domain_pool->model);
+	 domain_pool->update (domain_blocks, mp.indices,
+			      range->level, y_state, wfa, domain_pool->model);
+	 coeff->update (mp.weight, mp.into, range->level, coeff);
+	 
+	 Free (domain_blocks);
+      }
+      
+      for (edge = 0; isedge (mp.indices [edge]); edge++)
+      {
+	 range->into [edge]   = mp.into [edge];
+	 range->weight [edge] = mp.weight [edge];
+      }
+      range->into [edge]  = NO_EDGE;
+      range->matrix_bits  = mp.matrix_bits;
+      range->weights_bits = mp.weights_bits;
+      range->err          = mp.err;
+   }
+   else
+   {
+      range->into [0] = NO_EDGE;
+      mp.costs	      = MAXCOSTS;
+   }
+   
+   return mp.costs;
+}
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+static real_t norm_ortho_vector [MAXSTATES];     
+/*
+ *  Square-norm of the i-th vector of the orthogonal basis (OB)
+ *  ||o_i||^2; i = 0, ... ,n
+ */
+static real_t ip_image_ortho_vector [MAXEDGES];
+/* 
+ *  Inner product between the i-th vector of the OB and the given range: 
+ *  <b, o_i>; i = 0, ... ,n 
+ */
+static real_t ip_domain_ortho_vector [MAXSTATES][MAXEDGES];
+/* 
+ *  Inner product between the i-th vector of the OB and the image of domain j: 
+ *  <s_j, o_i>; j = 0, ... , wfa->states; i = 0, ... ,n, 
+ */
+static real_t rem_denominator [MAXSTATES];     
+static real_t rem_numerator [MAXSTATES];
+/*
+ *  At step n of the orthogonalization the comparitive value
+ *  (numerator_i / denominator_i):= <b, o_n>^2 / ||o_n|| ,
+ *  is computed for every domain i,
+ *  where o_n := s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k}
+ *  To avoid computing the same values over and over again,
+ *  the constant (remaining) parts of every domain are
+ *  stored in 'rem_numerator' and 'rem_denominator' separately
+ */
+static bool_t used [MAXSTATES];    
+/*
+ *  Shows whether a domain image was already used in a
+ *  linear combination (YES) or not (NO)
+ */
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void 
+matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
+		  unsigned max_edges, int y_state, const range_t *range,
+		  const domain_pool_t *domain_pool, const coeff_t *coeff,
+		  const wfa_t *wfa, const coding_t *c)
+/*
+ *  Find an approximation of the current 'range' with a linear
+ *  combination of vectors of the 'domain_pool'. The linear
+ *  combination is generated step by step with the matching pursuit
+ *  algorithm.  If flag 'full_search' is set then compute complete set
+ *  of linear combinations with n = {0, ..., 'max_edges'} vectors and
+ *  return the best one. Otherwise abort the computation as soon as
+ *  costs (LC (n + 1)) exceed costs ( LC (n)) and return the
+ *  sub-optimal solution.  'price' is the langrange multiplier
+ *  weighting rate and distortion.  'band' is the current color band
+ *  and 'y_state' the corresponding state in the Y component at same
+ *  pixel position.  'domain_pool' gives the set of available vectors,
+ *  and 'coeff' the model for the linear factors. The number of
+ *  elements in the linear combination is limited by 'max_edges'. In
+ *  'mp', vectors may be specified which should be excluded during the
+ *  approximation.
+ *  
+ *  No return value.
+ *
+ *  Side effects:
+ *	vectors, factors, rate, distortion and costs are stored in 'mp'
+ */
+{
+   unsigned	 n;			/* current vector of the OB */
+   int		 index;			/* best fitting domain image */
+   unsigned	 domain;		/* counter */
+   real_t	 norm;			/* norm of range image */
+   real_t	 additional_bits;	/* bits for mc, nd, and tree */
+   word_t	*domain_blocks;		/* current set of domain images */
+   const real_t  min_norm = 2e-3;	/* lower bound of norm */
+   unsigned 	 best_n   = 0;
+   unsigned	 size 	  = size_of_level (range->level);
+ 
+   /*
+    *  Initialize domain pool and inner product arrays
+    */
+   domain_blocks = domain_pool->generate (range->level, y_state, wfa,
+					  domain_pool->model);
+   for (domain = 0; domain_blocks [domain] >= 0; domain++)
+   {
+      used [domain] = NO;
+      rem_denominator [domain]		/* norm of domain */
+	 = get_ip_state_state (domain_blocks [domain], domain_blocks [domain],
+			       range->level, c);
+      if (rem_denominator [domain] / size < min_norm)
+	 used [domain] = YES;		/* don't use domains with small norm */
+      else
+	 rem_numerator [domain]		/* inner product <s_domain, b> */
+	    = get_ip_image_state (range->image, range->address,
+				  range->level, domain_blocks [domain], c);
+      if (!used [domain] && fabs (rem_numerator [domain]) < min_norm)
+	 used [domain] = YES;
+   }
+
+   /*
+    *  Exclude all domain blocks given in array 'mp->exclude'
+    */
+   for (n = 0; isdomain (mp->exclude [n]); n++)
+      used [mp->exclude [n]] = YES;
+
+   /*
+    *  Compute the approximation costs if 'range' is approximated with
+    *  no linear combination, i.e. the error is equal to the square
+    *  of the image norm and the size of the automaton is determined by
+    *  storing only zero elements in the current matrix row
+    */
+   for (norm = 0, n = 0; n < size; n++)
+      norm += square (c->pixels [range->address * size + n]);
+
+   additional_bits = range->tree_bits + range->mv_tree_bits
+		     + range->mv_coord_bits + range->nd_tree_bits
+		     + range->nd_weights_bits;
+
+   mp->err          = norm;
+   mp->weights_bits = 0;
+   mp->matrix_bits  = domain_pool->bits (domain_blocks, NULL, range->level,
+					 y_state, wfa, domain_pool->model);
+   mp->costs        = (mp->matrix_bits + mp->weights_bits
+		       + additional_bits) * price + mp->err;
+
+   n = 0;
+   do 
+   {
+      /*
+       *  Current approximation is: b = d_0 o_0 + ... + d_(n-1) o_(n-1)
+       *  with corresponding costs 'range->err + range->bits * p'.
+       *  For all remaining state images s_i (used[s_i] == NO) set
+       *  o_n :	= s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k}
+       *  and try to beat current costs.
+       *  Choose that vector for the next orthogonalization step,
+       *  which has minimal costs: s_index.
+       *  (No progress is indicated by index == -1)
+       */
+      
+      real_t min_matrix_bits  = 0;
+      real_t min_weights_bits = 0;
+      real_t min_error 	      = 0;
+      real_t min_weight [MAXEDGES];
+      real_t min_costs = full_search ? MAXCOSTS : mp->costs;
+      
+      for (index = -1, domain = 0; domain_blocks [domain] >= 0; domain++) 
+	 if (!used [domain]) 
+	 {
+	    real_t    matrix_bits, weights_bits;
+	    /*
+	     *  To speed up the search through the domain images,
+	     *  the costs of using domain image 'domain' as next vector
+	     *  can be approximated in a first step:
+	     *  improvement of image quality
+	     *	  <= square (rem_numerator[domain]) / rem_denominator[domain]
+	     */
+	    {
+		  word_t   vectors [MAXEDGES + 1];
+		  word_t   states [MAXEDGES + 1];
+		  real_t   weights [MAXEDGES + 1];
+		  unsigned i, k;
+		  
+		  for (i = 0, k = 0; k < n; k++)
+		     if (mp->weight [k] != 0)
+		     {
+			vectors [i] = mp->indices [k];
+			states [i]  = domain_blocks [vectors [i]];
+			weights [i] = mp->weight [k];
+			i++;
+		     }
+		  vectors [i] 	  = domain;
+		  states [i]  	  = domain_blocks [domain];
+		  weights [i] 	  = 0.5;
+		  vectors [i + 1] = -1;
+		  states [i + 1]  = -1;
+
+		  weights_bits = coeff->bits (weights, states, range->level,
+					      coeff);
+		  matrix_bits = domain_pool->bits (domain_blocks, vectors,
+						   range->level, y_state,
+						   wfa, domain_pool->model);
+	    }
+	    if (((matrix_bits + weights_bits + additional_bits) * price +
+		 mp->err -
+		 square (rem_numerator [domain]) / rem_denominator [domain])
+		< min_costs)
+	    {
+	       /*
+		*  1.) Compute the weights (linear factors) c_i of the
+		*  linear combination
+		*  b = c_0 v_0 + ... + c_(n-1) v_(n-1) + c_n v_'domain'
+		*  Use backward substitution to obtain c_i from the linear
+		*  factors of the lin. comb. b = d_0 o_0 + ... + d_n o_n
+		*  of the corresponding orthogonal vectors {o_0, ..., o_n}.
+		*  Vector o_n of the orthogonal basis is obtained by using
+		*  vector 'v_domain' in step n of the Gram Schmidt
+		*  orthogonalization (see above for definition of o_n).
+		*  Recursive formula for the coefficients c_i:
+		*  c_n := <b, o_n> / ||o_n||^2
+		*  for i = n - 1, ... , 0:
+		*  c_i := <b, o_i> / ||o_i||^2 +
+		*          \sum (k = i + 1, ... , n){ c_k <v_k, o_i>
+		*					/ ||o_i||^2 }
+		*  2.) Because linear factors are stored with reduced precision
+		*  factor c_i is rounded with the given precision in step i
+		*  of the recursive formula. 
+		*/
+
+	       unsigned k;		/* counter */
+	       int    	l;		/* counter */
+	       real_t 	m_bits;		/* number of matrix bits to store */
+	       real_t 	w_bits;		/* number of weights bits to store */
+	       real_t 	r [MAXEDGES];	/* rounded linear factors */
+	       real_t 	f [MAXEDGES];	/* linear factors */
+	       int    	v [MAXEDGES];	/* mapping of domains to vectors */
+	       real_t 	costs;		/* current approximation costs */
+	       real_t 	m_err;		/* current approximation error */
+
+	       f [n] = rem_numerator [domain] / rem_denominator [domain];
+	       v [n] = domain;		/* corresponding mapping */
+	       for (k = 0; k < n; k++)
+	       {
+		  f [k] = ip_image_ortho_vector [k] / norm_ortho_vector [k];
+		  v [k] = mp->indices [k];
+	       }
+	    
+	       for (l = n; l >= 0; l--) 
+	       {
+		  rpf_t *rpf = domain_blocks [v [l]]
+			       ? coeff->rpf : coeff->dc_rpf;
+
+		  r [l] = f [l] = btor (rtob (f [l], rpf), rpf);
+		     
+		  for (k = 0; k < (unsigned) l; k++)
+		     f [k] -= f [l] * ip_domain_ortho_vector [v [l]][k]
+			      / norm_ortho_vector [k] ;
+	       } 
+
+	       /*
+		*  Compute the number of output bits of the linear combination
+		*  and store the weights with reduced precision. The
+		*  resulting linear combination is
+		*  b = r_0 v_0 + ... + r_(n-1) v_(n-1) + r_n v_'domain'
+		*/
+	       {
+		  word_t vectors [MAXEDGES + 1];
+		  word_t states [MAXEDGES + 1];
+		  real_t weights [MAXEDGES + 1];
+		  int	 i;
+		  
+		  for (i = 0, k = 0; k <= n; k++)
+		     if (f [k] != 0)
+		     {
+			vectors [i] = v [k];
+			states [i]  = domain_blocks [v [k]];
+			weights [i] = f [k];
+			i++;
+		     }
+		  vectors [i] = -1;
+		  states [i]  = -1;
+
+		  w_bits = coeff->bits (weights, states, range->level, coeff);
+		  m_bits = domain_pool->bits (domain_blocks, vectors,
+					      range->level, y_state,
+					      wfa, domain_pool->model);
+	       }
+	       
+	       /*
+		*  To compute the approximation error, the corresponding
+		*  linear factors of the linear combination 
+		*  b = r_0 o_0 + ... + r_(n-1) o_(n-1) + r_n o_'domain'
+		*  with orthogonal vectors must be computed with following
+		*  formula:
+		*  r_i := r_i +
+		*          \sum (k = i + 1, ... , n) { r_k <v_k, o_i>
+		*					/ ||o_i||^2 }
+		*/
+	       for (l = 0; (unsigned) l <= n; l++)
+	       {
+		  /*
+		   *  compute <v_n, o_n>
+		   */
+		  real_t a;
+
+		  a = get_ip_state_state (domain_blocks [v [l]],
+					  domain_blocks [domain],
+					  range->level, c);
+		  for (k = 0; k < n; k++) 
+		     a -= ip_domain_ortho_vector [v [l]][k]
+			  / norm_ortho_vector [k]
+			  * ip_domain_ortho_vector [domain][k];
+		  ip_domain_ortho_vector [v [l]][n] = a;
+	       }
+	       norm_ortho_vector [n]     = rem_denominator [domain];
+	       ip_image_ortho_vector [n] = rem_numerator [domain];
+ 	    
+	       for (k = 0; k <= n; k++)
+		  for (l = k + 1; (unsigned) l <= n; l++)
+		     r [k] += ip_domain_ortho_vector [v [l]][k] * r [l]
+			      / norm_ortho_vector [k];
+	       /*
+		*  Compute approximation error:
+		*  error := ||b||^2 +
+		*  \sum (k = 0, ... , n){r_k^2 ||o_k||^2 - 2 r_k <b, o_k>}
+		*/
+	       m_err = norm;
+	       for (k = 0; k <= n; k++)
+		  m_err += square (r [k]) * norm_ortho_vector [k]
+			 - 2 * r [k] * ip_image_ortho_vector [k];
+	       if (m_err < 0)		/* TODO: return MAXCOSTS */
+		  warning ("Negative image norm: %f"
+			   " (current domain: %d, level = %d)",
+			   (double) m_err, domain, range->level);
+
+	       costs = (m_bits + w_bits + additional_bits) * price + m_err;
+	       if (costs < min_costs)	/* found a better approximation */
+	       {
+		  index            = domain;
+		  min_costs        = costs;
+		  min_matrix_bits  = m_bits;
+		  min_weights_bits = w_bits;
+		  min_error        = m_err;
+		  for (k = 0; k <= n; k++)
+		     min_weight [k] = f [k];
+	       }
+	    }
+	 }
+      
+      if (index >= 0)			/* found a better approximation */
+      {
+	 if (min_costs < mp->costs)
+	 {
+	    unsigned k;
+	    
+	    mp->costs        = min_costs;
+	    mp->err          = min_error;
+	    mp->matrix_bits  = min_matrix_bits;
+	    mp->weights_bits = min_weights_bits;
+	    
+	    for (k = 0; k <= n; k++)
+	       mp->weight [k] = min_weight [k];
+
+	    best_n = n + 1;
+	 }
+	 
+	 mp->indices [n] = index;
+	 mp->into [n]    = domain_blocks [index];
+
+	 used [index] = YES;
+
+	 /* 
+	  *  Gram-Schmidt orthogonalization step n 
+	  */
+	 orthogonalize (index, n, range->level, min_norm, domain_blocks, c);
+	 n++;
+      }	
+   } 
+   while (n < max_edges && index >= 0);
+
+   mp->indices [best_n] = NO_EDGE;
+   
+   mp->costs = (mp->matrix_bits + mp->weights_bits + additional_bits) * price
+	       + mp->err;
+
+   Free (domain_blocks);
+}
+
+static void
+orthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm,
+	       const word_t *domain_blocks, const coding_t *c)
+/*
+ *  Step 'n' of the Gram-Schmidt orthogonalization procedure:
+ *  vector 'index' is orthogonalized with respect to the set
+ *  {u_[0], ... , u_['n' - 1]}. The size of the image blocks is given by
+ *  'level'. If the denominator gets smaller than 'min_norm' then
+ *  the corresponding domain is excluded from the list of available
+ *  domain blocks.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	The remainder values (numerator and denominator) of
+ *	all 'domain_blocks' are updated. 
+ */
+{
+   unsigned domain;
+   
+   ip_image_ortho_vector [n] = rem_numerator [index];
+   norm_ortho_vector [n]     = rem_denominator [index];
+
+   /*
+    *  Compute inner products between all domain images and 
+    *  vector n of the orthogonal basis:
+    *  for (i = 0, ... , wfa->states)  
+    *  <s_i, o_n> := <s_i, v_n> -
+    *      \sum (k = 0, ... , n - 1){ <v_n, o_k> <s_i, o_k> / ||o_k||^2}
+    *  Moreover the denominator and numerator parts of the comparitive
+    *  value are updated.
+    */
+   for (domain = 0; domain_blocks [domain] >= 0; domain++) 
+      if (!used [domain]) 
+      {
+	 unsigned k;
+	 real_t   tmp = get_ip_state_state (domain_blocks [index],
+					    domain_blocks [domain], level, c);
+	 
+	 for (k = 0; k < n; k++) 
+	    tmp -= ip_domain_ortho_vector [domain][k] / norm_ortho_vector [k]
+		   * ip_domain_ortho_vector [index][k];
+	 ip_domain_ortho_vector [domain][n] = tmp;
+	 rem_denominator [domain] -= square (tmp) / norm_ortho_vector [n];
+	 rem_numerator [domain]   -= ip_image_ortho_vector [n]
+				     / norm_ortho_vector [n]
+				     * ip_domain_ortho_vector [domain][n] ;
+
+	 /*
+	  *  Exclude vectors with small denominator
+	  */
+	 if (!used [domain]) 
+	    if (rem_denominator [domain] / size_of_level (level) < min_norm) 
+	       used [domain] = YES;
+      }
+}
+
+
+
diff --git a/converter/other/fiasco/codec/approx.h b/converter/other/fiasco/codec/approx.h
new file mode 100644
index 00000000..c54b78c9
--- /dev/null
+++ b/converter/other/fiasco/codec/approx.h
@@ -0,0 +1,30 @@
+/*
+ *  approx.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _APPROX_H
+#define _APPROX_H
+
+#include "types.h"
+#include "cwfa.h"
+#include "domain-pool.h"
+
+real_t 
+approximate_range (real_t max_costs, real_t price, int max_edges,
+		   int y_state, range_t *range, domain_pool_t *domain_pool,
+		   coeff_t *coeff, const wfa_t *wfa, const coding_t *c);
+
+#endif /* not _APPROX_H */
+
diff --git a/converter/other/fiasco/codec/bintree.c b/converter/other/fiasco/codec/bintree.c
new file mode 100644
index 00000000..ddd74e15
--- /dev/null
+++ b/converter/other/fiasco/codec/bintree.c
@@ -0,0 +1,94 @@
+/*
+ *  bintree.c:		Bintree model of WFA tree	
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include <math.h>
+
+#include "bintree.h"
+#include "misc.h"
+#include "cwfa.h"
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+tree_update (bool_t child, unsigned level, tree_t *model)
+/*
+ *  Update tree model of given 'level'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	tree model is changed.
+ */
+{
+   if (!child)
+      model->total [level]++;
+   else
+   {
+      model->counts [level]++;
+      model->total [level]++;
+   }
+}
+
+real_t
+tree_bits (bool_t child, unsigned level, const tree_t *model)
+/*
+ *  Compute number of bits needed for coding element 'child' of the bintree.
+ *  For each 'level' a different context is used.
+ *
+ *  Return value:
+ *	# bits
+ */
+{
+   real_t prob = model->counts [level] / (real_t) model->total [level];
+
+   return child ? - log2 (prob) : - log2 (1 - prob);
+}
+
+void
+init_tree_model (tree_t *tree_model)
+/*
+ *  Initialize the model for the tree.
+ *  Symbol RANGE is synonymous with the '0' symbol and
+ *  symbol NO_RANGE is synonymous with the '1' symbol of the binary coder.
+ *  The 'count' array counts the number of NO_RANGE symbols.
+ *
+ *  No return value.
+ */
+{
+   unsigned level;
+   unsigned counts_0 [MAXLEVEL] = {20, 17, 15, 10, 5,  4,  3,
+				   2,  1,  1,  1,  1,  1,  1,  1,
+				   1,  1,  1,  1 , 1,  1,  1};
+   unsigned counts_1 [MAXLEVEL] = {1 , 1,  1,  1,  1,  1,  1,
+				   1,  1,  2,  3,  5,  10, 15, 20,
+				   25, 30, 35, 60, 60, 60, 60};
+   
+   for (level = 0; level < MAXLEVEL ; level++) 
+   {
+      tree_model->counts [level] = counts_1 [level];
+      tree_model->total [level]  = counts_0 [level] + counts_1 [level];
+   }
+}
diff --git a/converter/other/fiasco/codec/bintree.h b/converter/other/fiasco/codec/bintree.h
new file mode 100644
index 00000000..cdb80c94
--- /dev/null
+++ b/converter/other/fiasco/codec/bintree.h
@@ -0,0 +1,43 @@
+/*
+ *  bintree.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _BINTREE_H
+#define _BINTREE_H
+
+#include "wfa.h"
+#include "types.h"
+
+typedef struct tree
+/*
+ *  Used for estimating the number of bits needed for storing the
+ *  tree array. For each level a different context is used.
+ *  The binary alphabet consists of the two symbols NO_RANGE and RANGE,
+ *  which indicate whether there exists a tree edge or not.
+ */
+{
+   unsigned counts [MAXLEVEL];		/* # NO_RANGE symbols at given level */
+   unsigned total [MAXLEVEL];		/* total number of symbols at  ''   */
+} tree_t;
+
+real_t
+tree_bits (bool_t child, unsigned level, const tree_t *model);
+void
+init_tree_model (tree_t *tree_model);
+void
+tree_update (bool_t child, unsigned level, tree_t *model);
+
+#endif /* not _BINTREE_H */
+
diff --git a/converter/other/fiasco/codec/coder.c b/converter/other/fiasco/codec/coder.c
new file mode 100644
index 00000000..df878d87
--- /dev/null
+++ b/converter/other/fiasco/codec/coder.c
@@ -0,0 +1,965 @@
+/*
+ *  coder.c:		WFA coder toplevel functions
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+#include "pnm.h"
+
+#include <math.h>
+#include <ctype.h>
+
+#include <string.h>
+
+#include "nstring.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "fiasco.h"
+
+#include "cwfa.h"
+#include "misc.h"
+#include "control.h"
+#include "bintree.h"
+#include "subdivide.h"
+#include "read.h"
+#include "write.h"
+#include "image.h"
+#include "mwfa.h"
+#include "list.h"
+#include "decoder.h"
+#include "motion.h"
+#include "wfalib.h"
+#include "domain-pool.h"
+#include "coeff.h"
+#include "coder.h"
+#include "rpf.h"
+
+/*****************************************************************************
+
+				global variables
+  
+*****************************************************************************/
+
+const real_t MAXCOSTS =	1e20;
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static coding_t *
+alloc_coder (char const * const *inputname, const c_options_t *options,
+	     wfa_info_t *wi);
+static void
+free_coder (coding_t *c);
+static char *
+get_input_image_name (char const * const *templptr, unsigned ith_image);
+static void
+video_coder (char const * const *image_template, bitfile_t *output,
+	     wfa_t *wfa, coding_t *c);
+static void 
+frame_coder (wfa_t *wfa, coding_t *c, bitfile_t *output);
+static void
+print_statistics (char c, real_t costs, const wfa_t *wfa, const image_t *image,
+		  const range_t *range);
+static frame_type_e
+pattern2type (unsigned frame, const char *pattern);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+int
+fiasco_coder (char const * const *inputname, const char *outputname,
+	      float quality, const fiasco_c_options_t *options)
+/*
+ *  FIASCO coder.
+ *  Encode image or video frames given by the array of filenames `inputname'
+ *  and write to the outputfile `outputname'.
+ *  If 'inputname' = NULL or
+ *     'inputname [0]' == NULL or
+ *     'inputname [0]' == "-", read standard input.
+ *  If 'outputname' == NULL or "-", write on standard output.
+ *  'quality' defines the approximation quality and is 1 (worst) to 100 (best).
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   try
+   {
+      char const * const default_input [] = {"-", NULL};
+      fiasco_c_options_t *default_options = NULL;
+      const c_options_t  *cop;
+      char const * const *template;
+      
+      /*
+       *  Check parameters
+       */
+      if (!inputname || !inputname [0] || streq (inputname [0], "-"))
+	 template = default_input;
+      else
+	 template = inputname;
+      
+      if (quality <= 0)
+      {
+	 set_error (_("Compression quality has to be positive."));
+	 return 0;
+      }
+      else if (quality >= 100)
+      {
+	 warning (_("Quality typically is 1 (worst) to 100 (best).\n"
+		    "Be prepared for a long running time."));
+      }
+
+      if (options)
+      {
+	 cop = cast_c_options ((fiasco_c_options_t *) options);
+	 if (!cop)
+	    return 0;
+      }
+      else
+      {
+	 default_options = fiasco_c_options_new ();
+	 cop 		 = cast_c_options (default_options);
+      }
+
+   /*
+    *  Open output stream and initialize WFA
+    */
+      {
+	 bitfile_t *output = open_bitfile (outputname, "FIASCO_DATA",
+					   WRITE_ACCESS);
+	 if (!output)
+	 {
+	    set_error (_("Can't write outputfile `%s'.\n%s"),
+		       outputname ? outputname : "<stdout>",
+		       get_system_error ());
+	    if (default_options)
+	       fiasco_c_options_delete (default_options);
+	    return 0;
+	 }
+	 else
+	 {
+	    wfa_t    *wfa = alloc_wfa (YES);
+	    coding_t *c   = alloc_coder (template, cop, wfa->wfainfo);
+	 
+	    read_basis (cop->basis_name, wfa);
+	    append_basis_states (wfa->basis_states, wfa, c);
+	 
+	    c->price = 128 * 64 / quality;
+	 
+	    video_coder (template, output, wfa, c);
+	 
+	    close_bitfile (output);
+	    free_wfa (wfa);
+	    free_coder (c);
+	 
+	    if (default_options)
+	       fiasco_c_options_delete (default_options);
+	 }
+      }
+      return 1;
+   }
+   catch
+   {
+      return 0;
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static coding_t *
+alloc_coder (char const * const *inputname, const c_options_t *options,
+	     wfa_info_t *wi)
+/*
+ *  Coder structure constructor.
+ *  Allocate memory for the FIASCO coder structure and
+ *  fill in default values specified by 'options'.
+ *
+ *  Return value:
+ *	pointer to the new coder structure or NULL on error
+ */
+{
+   coding_t *c = NULL;
+   
+   /*
+    *  Check whether all specified image frames are readable and of same type
+    */
+   {
+      char     *filename;
+      int   	width, w = 0, height, h = 0;
+      bool_t	color, c = NO;
+      unsigned 	n;
+      
+      for (n = 0; (filename = get_input_image_name (inputname, n)); n++)
+      {
+          FILE *file;
+          xelval maxval;
+          int format;
+          if (filename == NULL)
+              file = stdin;
+          else
+              file = pm_openr(filename);
+          pnm_readpnminit(file, &width, &height, &maxval, &format);
+          color = (PNM_FORMAT_TYPE(format) == PPM_FORMAT) ? TRUE: FALSE;
+
+          pm_close(file);
+	 if (n)
+	 {
+	    if (w != width || h != height || c != color)
+	    {
+	       set_error (_("Format of image frame `%s' doesn't match."),
+			  filename ? filename : "<stdin>");
+	       return NULL;
+	    }
+	 }
+	 else
+	 {
+	    w = width;
+	    h = height;
+	    c = color;
+	 }
+	 Free (filename);
+      }
+      wi->frames = n;
+      wi->width  = w;
+      wi->height = h;
+      wi->color  = c;
+   }
+
+   /*
+    *  Levels ...
+    */
+   {
+      unsigned lx, ly;
+      
+      lx = (unsigned) (log2 (wi->width - 1) + 1);
+      ly = (unsigned) (log2 (wi->height - 1) + 1);
+      
+      wi->level = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0);
+   }
+   
+   c = Calloc (1, sizeof (coding_t));
+
+   c->options 	      	   = *options;
+   c->options.lc_min_level = max (options->lc_min_level, 3);
+   c->options.lc_max_level = min (options->lc_max_level, wi->level - 1);
+
+   c->tiling = alloc_tiling (options->tiling_method,
+			     options->tiling_exponent, wi->level);
+
+   if (wi->frames > 1 && c->tiling->exponent > 0)
+   {
+      c->tiling->exponent = 0;
+      warning (_("Image tiling valid only with still image compression."));
+   }
+
+   if (c->options.lc_max_level >= wi->level - c->tiling->exponent)
+   {
+      message ("'max_level' changed from %d to %d due to image tiling level.",
+	       c->options.lc_max_level, wi->level - c->tiling->exponent - 1);
+      c->options.lc_max_level = wi->level - c->tiling->exponent - 1;
+   }
+   
+   if (c->options.lc_min_level > c->options.lc_max_level)
+      c->options.lc_min_level = c->options.lc_max_level;
+   
+   /*
+    *  p_min_level, p_max_level min and max level for ND/MC prediction
+    *  [p_min_level, p_max_level] must be a subset of [min_level, max_level] !
+    */
+   wi->p_min_level = max (options->p_min_level, c->options.lc_min_level);
+   wi->p_max_level = min (options->p_max_level, c->options.lc_max_level);
+   if (wi->p_min_level > wi->p_max_level)
+      wi->p_min_level = wi->p_max_level;
+
+   c->options.images_level = min (c->options.images_level,
+				  c->options.lc_max_level - 1);
+   
+   c->products_level  = max (0, ((signed int) c->options.lc_max_level
+				 - (signed int) c->options.images_level - 1));
+   c->pixels 	      = Calloc (size_of_level (c->options.lc_max_level),
+				sizeof (real_t));
+   c->images_of_state = Calloc (MAXSTATES, sizeof (real_t *));
+   c->ip_images_state = Calloc (MAXSTATES, sizeof (real_t *));
+   c->ip_states_state = Calloc (MAXSTATES * MAXLEVEL, sizeof (real_t *));
+   
+   debug_message ("Imageslevel :%d, Productslevel :%d",
+		  c->options.images_level, c->products_level);
+   debug_message ("Memory : (%d + %d + %d * 'states') * 'states' + %d",
+		  size_of_tree (c->options.images_level) * 4,
+		  size_of_tree (c->products_level) * 4,
+		  (c->options.lc_max_level - c->options.images_level),
+		  size_of_level (c->options.lc_max_level));
+   
+   /*
+    *  Domain pools ...
+    */
+   c->domain_pool   = NULL;
+   c->d_domain_pool = NULL;
+
+   /*
+    *  Coefficients model ...
+    */
+   c->coeff   = NULL;
+   c->d_coeff = NULL;
+
+   /*
+    *  Max. number of states and edges
+    */
+   wi->max_states   	   = max (min (options->max_states, MAXSTATES), 1);
+   c->options.max_elements = max (min (options->max_elements, MAXEDGES), 1);
+
+   /*
+    *  Title and comment strings
+    */
+   wi->title   = strdup (options->title);
+   wi->comment = strdup (options->comment);
+   
+   /*
+    *  Reduced precision format
+    */
+   wi->rpf
+      = alloc_rpf (options->rpf_mantissa, options->rpf_range);
+   wi->dc_rpf
+      = alloc_rpf (options->dc_rpf_mantissa, options->dc_rpf_range);
+   wi->d_rpf
+      = alloc_rpf (options->d_rpf_mantissa, options->d_rpf_range);
+   wi->d_dc_rpf
+      = alloc_rpf (options->d_dc_rpf_mantissa, options->d_dc_rpf_range);
+   
+   /*
+    *  Color image options ...
+    */
+   wi->chroma_max_states = max (1, options->chroma_max_states);
+
+   /*
+    *  Set up motion compensation struct.
+    *  p_min_level, p_max_level are also used for ND prediction
+    */
+   wi->search_range   = options->search_range;
+   wi->fps 	      = options->fps;
+   wi->half_pixel     = options->half_pixel_prediction;
+   wi->cross_B_search = options->half_pixel_prediction;
+   wi->B_as_past_ref  = options->B_as_past_ref;
+   wi->smoothing      = options->smoothing;
+   
+   c->mt = alloc_motion (wi);
+
+   return c;
+}
+
+static void
+free_coder (coding_t *c)
+/*
+ *  Coder struct destructor:
+ *  Free memory of 'coder' struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'coder' is discarded.
+ */
+{
+   free_tiling (c->tiling);
+   free_motion (c->mt);
+   
+   Free (c->pixels);
+   Free (c->images_of_state);
+   Free (c->ip_images_state);
+   Free (c->ip_states_state);
+   Free (c);
+}
+
+static char *
+get_input_image_name (char const * const *templptr, unsigned ith_image)
+/*
+ *  Construct the i-th image-name using templates.
+ *  If the template contains a '[' it must be of the form
+ *  "prefix[start-end{+,-}step]suffix"
+ *  where "{+,-}step" is optional.
+ *  Leading zeros of "start" are significant.
+ *
+ *  Example:
+ *   "image0[12-01-1].pgm" yields image012.pgm, image011.pgm, ..., image001.pgm
+ *
+ *  Return value:
+ *      ptr to name of image 'ith_image' or NULL if ith_image is out of range.
+ */
+{
+   while (*templptr)
+   {
+      const char *template = *templptr++;
+      char       *s;
+
+      if (!(s = strchr (template, '['))) /* no template, just a filename */
+      {
+	 if (ith_image == 0)
+	    return strdup (template);
+	 else
+	    ith_image--;
+      }
+      else				/* template parser */
+      {
+	 unsigned  n_digits;		/* # of digits in image name no. */
+	 char 	  *s2;
+	 char 	  *suffix;		/* characters after template end */
+	 char  	   prefix [MAXSTRLEN];	/* chars up to the template start */
+	 unsigned  first;		/* first image number */
+	 unsigned  last;		/* last image number */
+	 int  	   image_num;		/* current image number */
+	 int   	   increment = 1;
+	 int 	   dummy;
+
+	 strcpy (prefix, template);
+	 prefix [s - template] = '\0';
+   
+	 for (s2 = ++s, n_digits = 0; ISDIGIT (*s2); s2++, n_digits++)
+	    ;
+	 if (sscanf (s, "%d", &dummy) == 0 || dummy < 0)
+	    error ("Input name template conversion failure.\n"
+		   "Check spelling of template.");
+	 first = (unsigned) dummy;
+	 
+	 if (*s2++ != '-')
+	    error ("Input name template conversion failure.\n"
+		   "Check spelling of template.");
+   
+	 for (s = s2; ISDIGIT (*s2); s2++)
+	    ;
+	 if (sscanf (s, "%d", &dummy) == 0 || dummy < 0)
+	    error ("Input name template conversion failure.\n"
+		   "Check spelling of template.");
+	 last = (unsigned) dummy;
+	 
+	 if (*s2 == '+' || *s2 == '-') 
+	 {
+	    for (s = s2++; ISDIGIT (*s2); s2++)
+	       ;
+	    if (sscanf (s, "%d", &increment) == 0)
+	       error ("Input name template conversion failure.\n"
+		      "Check spelling of template.");
+	 } 	 
+	 if (*s2 != ']')
+	    error ("Input name template conversion failure.\n"
+		   "Check spelling of template.");
+	 suffix = s2 + 1;
+   
+	 image_num = first + increment * ith_image;
+	 if (image_num < 0)
+	    error ("Input name template conversion failure.\n"
+		   "Check spelling of template.");
+	 
+	 if ((increment >  0 && (unsigned) image_num > last) || 
+	     (increment <= 0 && (unsigned) image_num < last))
+	 {
+	    /* TODO: check this */
+	    ith_image -= (last - first) / increment + 1;
+	 }
+	 else
+	 {
+	    char formatstr [MAXSTRLEN]; /* format string for image filename */
+	    char image_name [MAXSTRLEN]; /* image file name to be composed */
+	    
+	    strcpy (formatstr, "%s%0?d%s");
+	    formatstr [4] = '0' + (char) n_digits;
+	    sprintf (image_name, formatstr, prefix, image_num, suffix);
+	    return strdup (image_name);
+	 }
+      }
+   }
+   return NULL;
+}	
+
+static void
+video_coder (char const * const *image_template, bitfile_t *output,
+	     wfa_t *wfa, coding_t *c)
+/*
+ *  Toplevel function to encode a sequence of video frames specified
+ *  by 'image_template'. The output is written to stream 'output'.
+ *  Coding options are given by 'c'.
+ *
+ *  No return value.
+ */
+{
+   unsigned  display;			/* picture number in display order */
+   int	     future_display;		/* number of future reference */
+   int	     frame;			/* current frame number */
+   char	    *image_name;		/* image name of current frame */
+   image_t  *reconst 	  = NULL; 	/* decoded reference image */
+   bool_t    future_frame = NO;		/* YES if last frame was in future */
+   
+   debug_message ("Generating %d WFA's ...", wfa->wfainfo->frames);
+
+   future_display = -1;
+   frame          = -1;
+   display        = 0;
+
+   while ((image_name = get_input_image_name (image_template, display)))
+   {
+      frame_type_e type;		/* current frame type: I, B, P */
+      
+      /*
+       *  Determine type of next frame.
+       *  Skip already coded frames (future reference!)
+       */
+      if (display == 0 && !c->options.reference_filename)
+	 type = I_FRAME;		/* Force first frame to be intra */
+      else
+	 type = pattern2type (display, c->options.pattern);
+      
+      if (type != I_FRAME && c->options.reference_filename)
+	 /* Load reference from disk */
+      {
+	 debug_message ("Reading reference frame `%s'.",
+			c->options.reference_filename);
+	 reconst 	 = read_image (c->options.reference_filename);
+	 c->options.reference_filename = NULL;
+      }
+      if ((int) display == future_display) /* Skip already coded future ref */
+      {				
+	 display++;
+	 continue;
+      }	  
+      else if (type == B_FRAME && (int) display > future_display) 
+      {
+	 unsigned i = display;
+	 /*
+	  *  Search for future reference
+	  */
+	 while (type == B_FRAME)
+	 {
+	    char *name;			/* image name of future frame */
+
+	    i++;
+	    name = get_input_image_name (image_template, i);
+	    
+	    if (!name)			/* Force last valid frame to be 'P' */
+	    {
+	       future_display = i - 1;
+	       type = P_FRAME;
+	    }
+	    else
+	    {
+	       future_display = i;    
+	       image_name     = name;
+	       type 	      = pattern2type (i, c->options.pattern);
+	    }
+	    frame = future_display;
+	 }
+      }
+      else
+      {
+	 frame = display;
+	 display++;
+      }
+
+      debug_message ("Coding \'%s\' [%c-frame].", image_name,
+		     type == I_FRAME ? 'I' : (type == P_FRAME ? 'P' : 'B'));
+       
+      /*
+       *  Depending on current frame type update past and future frames
+       *  which are needed as reference frames.
+       */
+      c->mt->frame_type = type;
+      if (type == I_FRAME)
+      {
+	 if (c->mt->past)		/* discard past frame */
+	    free_image (c->mt->past);
+	 c->mt->past = NULL;
+	 if (c->mt->future)		/* discard future frame */
+	    free_image (c->mt->future);
+	 c->mt->future = NULL;
+	 if (reconst)			/* discard current frame */
+	    free_image (reconst);
+	 reconst = NULL;
+      }
+      else if (type == P_FRAME)
+      {
+	 if (c->mt->past)		/* discard past frame */
+	    free_image (c->mt->past);
+	 c->mt->past = reconst;		/* past frame <- current frame */
+	 reconst    = NULL;
+	 if (c->mt->future)		/* discard future frame */
+	    free_image (c->mt->future);
+	 c->mt->future = NULL;
+      }
+      else				/* B_FRAME */
+      {
+	 if (future_frame)		/* last frame was future frame */
+	 {
+	    if (c->mt->future)		/* discard future frame */
+	       free_image (c->mt->future);
+	    c->mt->future = reconst;	/* future frame <- current frame */
+	    reconst      = NULL;
+	 }
+	 else
+	 {
+	    if (wfa->wfainfo->B_as_past_ref == YES)
+	    {
+	       if (c->mt->past)		/* discard past frame */
+		  free_image (c->mt->past);
+	       c->mt->past = reconst;	/* past frame <- current frame */
+	       reconst    = NULL;
+	    }
+	    else
+	    {
+	       if (reconst)		/* discard current frame */
+		  free_image (reconst);
+	       reconst = NULL;
+	    }
+	 }
+      }
+
+      /*
+       *  Start WFA coding of current frame
+       */
+      future_frame   = frame == future_display;
+      c->mt->number   = frame;
+      c->mt->original = read_image (image_name);
+      if (c->tiling->exponent && type == I_FRAME) 
+	 perform_tiling (c->mt->original, c->tiling);
+
+      frame_coder (wfa, c, output);
+
+      /*
+       *  Regenerate image:
+       *  1. Compute approximation of WFA ranges (real image bintree order)
+       *  2. Generate byte image in rasterscan order
+       *  3. Apply motion compensation
+       */
+      reconst = decode_image (wfa->wfainfo->width, wfa->wfainfo->height,
+			      FORMAT_4_4_4, NULL, wfa);
+
+      if (type != I_FRAME)
+	 restore_mc (0, reconst, c->mt->past, c->mt->future, wfa);
+
+      if (c->mt->original)
+	 free_image (c->mt->original);
+      c->mt->original = NULL;
+      
+      remove_states (wfa->basis_states, wfa); /* Clear WFA structure */
+   }
+
+   if (reconst)
+      free_image (reconst);
+   if (c->mt->future)
+      free_image (c->mt->future);
+   if (c->mt->past)
+      free_image (c->mt->past);
+   if (c->mt->original)
+      free_image (c->mt->original);
+}
+
+static frame_type_e
+pattern2type (unsigned frame, const char *pattern)
+{
+    int tmp = TOUPPER (pattern [frame % strlen (pattern)]);
+    frame_type_e retval;
+
+    switch (tmp)
+    {
+    case 'I':
+        retval = I_FRAME;
+        break;
+    case 'B':
+        retval = B_FRAME;
+        break;
+    case 'P':
+        retval = P_FRAME;
+        break;
+    default:
+        error ("Frame type %c not valid. Choose one of I,B or P.", tmp);
+    }
+    return retval;
+}
+
+static void 
+frame_coder (wfa_t *wfa, coding_t *c, bitfile_t *output)
+/*
+ * 
+ *  WFA Coding of next frame.  All important coding parameters are
+ *  stored in 'c'.  The generated 'wfa' is written to stream 'output'
+ *  immediately after coding.
+ *
+ *  No return value.
+ */
+{
+   unsigned state;
+   range_t  range;			/* first range == the entire image */
+   real_t   costs;			/* total costs (minimized quantity) */
+   unsigned bits;			/* number of bits written on disk */
+   clock_t  ptimer;
+   
+   prg_timer (&ptimer, START);
+
+   bits = bits_processed (output);
+   
+   init_tree_model (&c->tree);
+   init_tree_model (&c->p_tree);
+
+   c->domain_pool
+      = alloc_domain_pool (c->options.id_domain_pool,
+			   wfa->wfainfo->max_states,
+			   c->options.max_elements, wfa);
+   c->d_domain_pool
+      = alloc_domain_pool ((c->options.prediction
+			    || c->mt->frame_type != I_FRAME)
+			   ? c->options.id_d_domain_pool : "constant",
+			   wfa->wfainfo->max_states,
+			   c->options.max_elements, wfa);
+
+   c->coeff   = alloc_coeff_model (c->options.id_rpf_model,
+				   wfa->wfainfo->rpf,
+				   wfa->wfainfo->dc_rpf,
+				   c->options.lc_min_level,
+				   c->options.lc_max_level);
+   c->d_coeff = alloc_coeff_model (c->options.id_d_rpf_model,
+				   wfa->wfainfo->d_rpf,
+				   wfa->wfainfo->d_dc_rpf,
+				   c->options.lc_min_level,
+				   c->options.lc_max_level);
+
+   if (!c->mt->original->color)		/* grayscale image */
+   {
+      memset (&range, 0, sizeof (range_t));
+      range.level = wfa->wfainfo->level;
+
+      costs = subdivide (MAXCOSTS, GRAY, RANGE, &range, wfa, c,
+			 c->options.prediction || c->mt->frame_type != I_FRAME,
+			 NO);
+      if (c->options.progress_meter != FIASCO_PROGRESS_NONE)
+	 message ("");
+
+      if (isrange (range.tree))		/* entire image is approx. by lc? */
+	 error ("No root state generated!");
+      else
+	 wfa->root_state = range.tree;
+
+      print_statistics ('\0', costs, wfa, c->mt->original, &range);
+   }
+   else
+   {
+      int     YCb_node = -1;
+      int     tree [3];			/* 3 root states of each color comp. */
+      color_e band;
+      
+      /*
+       *  When compressing color images, the three color components (YCbCr) 
+       *  are copied into a large image:
+       *  [  Y  Cr ]
+       *  [  Cb 0  ]
+       *  I.e. the color components of an image are processed in a row.
+       *  After all components are compressed, virtual states are generated
+       *  to describe the large image.
+       */
+      for (band = first_band (YES); band <= last_band (YES) ; band++)
+      {
+	 debug_message ("Encoding color component %d", band);
+	 tree [band] = RANGE;
+	 if (band == Cb)
+	 {
+	    unsigned min_level;
+
+	    c->domain_pool->chroma (wfa->wfainfo->chroma_max_states, wfa,
+				    c->domain_pool->model);
+	    /*
+	     *  Don't use a finer partioning for the chrominancy bands than for
+	     *  the luminancy band.
+	     */
+	    for (min_level = MAXLEVEL, state = wfa->basis_states;
+		 state < wfa->states; state++)
+	    {
+	       unsigned lincomb, label;
+	       
+	       for (lincomb = 0, label = 0; label < MAXLABELS; label++)
+		  lincomb += isrange (wfa->tree [state][label]) ? 1 : 0;
+	       if (lincomb)
+		  min_level = min (min_level,
+				   (unsigned) (wfa->level_of_state [state]
+					       - 1));
+	    }
+	    c->options.lc_min_level = min_level;
+	    if (c->mt->frame_type != I_FRAME) /* subtract mc of luminance */
+	       subtract_mc (c->mt->original, c->mt->past, c->mt->future, wfa);
+	 }
+
+	 memset (&range, 0, sizeof (range_t));
+	 range.level = wfa->wfainfo->level;
+	 
+	 costs = subdivide (MAXCOSTS, band, tree [Y], &range, wfa, c,
+			    c->mt->frame_type != I_FRAME && band == Y, NO);
+	 if (c->options.progress_meter != FIASCO_PROGRESS_NONE)
+	    message ("");
+	 {
+	    char colors [] = {'Y', 'B', 'R'};
+	    
+	    print_statistics (colors [band], costs, wfa,
+			      c->mt->original, &range);
+	 }
+	 
+	 if (isrange (range.tree))	/* whole image is approx. by a l.c. */
+	    error ("No root state generated for color component %d!", band);
+	 else
+	    tree[band] = range.tree;
+	 
+	 if (band == Cb)
+	 {
+	    wfa->tree [wfa->states][0] = tree[Y];
+	    wfa->tree [wfa->states][1] = tree[Cb];
+	    YCb_node = wfa->states;
+	    append_state (YES, compute_final_distribution (wfa->states, wfa),
+			  wfa->wfainfo->level + 1, wfa, c);
+	 }
+      }
+      /*
+       *  generate two virtual states (*) 
+       *
+       *              *
+       *            /   \
+       *           +     *
+       *          / \   /  
+       *         Y   CbCr 
+       */
+      wfa->tree [wfa->states][0] = tree[Cr];
+      wfa->tree [wfa->states][1] = RANGE;
+      append_state (YES, compute_final_distribution (wfa->states, wfa),
+		    wfa->wfainfo->level + 1, wfa, c);
+      wfa->tree[wfa->states][0] = YCb_node;
+      wfa->tree[wfa->states][1] = wfa->states - 1;
+      append_state (YES, compute_final_distribution (wfa->states, wfa),
+		    wfa->wfainfo->level + 2, wfa, c);
+
+      wfa->root_state = wfa->states - 1;
+   }
+
+   for (state = wfa->basis_states; state < MAXSTATES; state++)
+   {
+      unsigned level;
+      
+      if (c->images_of_state [state])
+      {
+	 Free (c->images_of_state [state]);
+	 c->images_of_state [state] = NULL;
+      }
+      if (c->ip_images_state [state])
+      {
+	 Free (c->ip_images_state [state]);
+	 c->ip_images_state [state] = NULL;
+      }
+      for (level = c->options.images_level + 1;
+	   level <= c->options.lc_max_level;
+	   level++)
+	 if (c->ip_states_state [state][level])
+	 {
+	    Free (c->ip_states_state [state][level]);
+	    c->ip_states_state [state][level] = NULL;
+	 }
+      
+   }
+   
+   locate_delta_images (wfa);
+   write_next_wfa (wfa, c, output);
+   
+   bits = bits_processed (output) - bits;
+   debug_message ("Total number of bits written: %d (%d bytes, %5.3f bpp)",
+		  bits, bits >> 3,
+		  bits / (double) (c->mt->original->height
+				   * c->mt->original->width));
+   debug_message ("Total encoding time (real): %d sec",
+		  prg_timer (&ptimer, STOP) / 1000);
+
+   c->domain_pool->free (c->domain_pool);
+   c->d_domain_pool->free (c->d_domain_pool);
+
+   c->coeff->free (c->coeff);
+   c->d_coeff->free (c->d_coeff);
+}
+
+static void
+print_statistics (char c, real_t costs, const wfa_t *wfa, const image_t *image,
+		  const range_t *range)
+{
+   unsigned max_level, min_level, state, label, lincomb;
+   
+   for (max_level = 0, min_level = MAXLEVEL, state = wfa->basis_states;
+	state < wfa->states; state++)
+   {
+      for (lincomb = 0, label = 0; label < MAXLABELS; label++)
+	 lincomb += isrange(wfa->tree[state][label]) ? 1 : 0;
+	 
+      if (lincomb)
+      {
+	 max_level = max (max_level,
+			  (unsigned) (wfa->level_of_state [state] - 1));
+	 min_level = min (min_level,
+			  (unsigned) (wfa->level_of_state [state] - 1));
+      }
+   }
+   debug_message ("Image partitioning: maximum level %d , minimum level %d",
+		  max_level, min_level);
+   debug_message ("WFA contains %d states (%d basis states).",
+		  wfa->states, wfa->basis_states);
+   debug_message ("Estimated error: %.2f (RMSE: %.2f, PSNR: %.2f dB).",
+		  (double) range->err,
+		  sqrt (range->err / image->width / image->height),
+		  10 * log ( 255.0 * 255.0 /
+			     (range->err / image->width / image->height))
+		  / log (10.0));
+   debug_message ("Estimated filesize: %.0f bits (%.0f bytes).",
+		  (double) (range->tree_bits + range->matrix_bits
+			    + range->weights_bits
+			    + range->mv_tree_bits + range->mv_coord_bits
+			    + range->nd_tree_bits + range->nd_weights_bits),
+		  (double) (range->tree_bits + range->matrix_bits
+			    + range->weights_bits + range->mv_tree_bits
+			    + range->mv_coord_bits + range->nd_tree_bits
+			    + range->nd_weights_bits) / 8);
+   if (c)
+      debug_message ("(%cT: %.0f, %cM: %.0f, %cW: %.0f, %cMC: %.0f, "
+		     "%cMV: %.0f, %cNT: %.0f, %cNW: %.0f.)",
+		     c, (double) range->tree_bits,
+		     c, (double) range->matrix_bits,
+		     c, (double) range->weights_bits,
+		     c, (double) range->mv_tree_bits,
+		     c, (double) range->mv_coord_bits,
+		     c, (double) range->nd_tree_bits,
+		     c, (double) range->nd_weights_bits);
+   else
+      debug_message ("(T: %.0f, M: %.0f, W: %.0f, MC: %.0f, MV: %.0f, "
+		     "NT: %.0f, NW: %.0f.)",
+		     (double) range->tree_bits,
+		     (double) range->matrix_bits,
+		     (double) range->weights_bits,
+		     (double) range->mv_tree_bits,
+		     (double) range->mv_coord_bits,
+		     (double) range->nd_tree_bits,
+		     (double) range->nd_weights_bits);
+   debug_message ("Total costs : %.2f", (double) costs);
+}
diff --git a/converter/other/fiasco/codec/coder.h b/converter/other/fiasco/codec/coder.h
new file mode 100644
index 00000000..c6f4bb7c
--- /dev/null
+++ b/converter/other/fiasco/codec/coder.h
@@ -0,0 +1,24 @@
+/*
+ *  coder.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _CODER_H
+#define _CODER_H
+
+#include "types.h"
+#include "cwfa.h"
+
+#endif /* not _CODER_H */
+
diff --git a/converter/other/fiasco/codec/coeff.c b/converter/other/fiasco/codec/coeff.c
new file mode 100644
index 00000000..0cd64f17
--- /dev/null
+++ b/converter/other/fiasco/codec/coeff.c
@@ -0,0 +1,369 @@
+/*
+ *  coeff.c:		Matching pursuit coefficients probability model
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include <string.h>
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "rpf.h"
+#include "misc.h"
+#include "coeff.h"
+
+/*
+ *  Coefficient model interface:
+ *  Implementing the coefficients model interface requires the
+ *  following steps: 
+ *  - Add a constructor that initializes the coeff_t structure
+ *  - Allocate new model with default_alloc() 
+ *  - Fill the c_array_t coeff_models[] array with constructor and name
+ *  - Write code for methods bits() and update()
+ *  - Either use default functions for remaining methods or override them
+ *  The new model is automatically registered at the command line.
+ */
+
+/*****************************************************************************
+		  uniform distribution coefficients model
+*****************************************************************************/
+
+static coeff_t *
+alloc_uniform_coeff_model (rpf_t *rpf, rpf_t *dc_rpf,
+			   unsigned min_level, unsigned max_level);
+static void
+uniform_update (const real_t *used_coeff, const word_t *used_states,
+		unsigned level, coeff_t *coeff);
+static real_t
+uniform_bits (const real_t *used_coeff, const word_t *used_states,
+	      unsigned level, const coeff_t *coeff);
+
+/*****************************************************************************
+			  default functions
+*****************************************************************************/
+
+static void
+default_model_free (void *model);
+static void *
+default_model_duplicate (const coeff_t *coeff, const void *model);
+static void
+default_free (coeff_t *coeff);
+static coeff_t *
+default_alloc (rpf_t *rpf, rpf_t *dc_rpf,
+	       unsigned min_level, unsigned max_level);
+
+/*****************************************************************************
+		adaptive arithmetic coding model
+*****************************************************************************/
+
+static coeff_t *
+alloc_aac_coeff_model (rpf_t *rpf, rpf_t *dc_rpf,
+		       unsigned min_level, unsigned max_level);
+static void
+aac_model_free (void *model);
+static void *
+aac_model_alloc (const coeff_t *coeff);
+static void *
+aac_model_duplicate (const coeff_t *coeff, const void *model);
+static void
+aac_update (const real_t *used_coeff, const word_t *used_states,
+	    unsigned level, coeff_t *coeff);
+static real_t
+aac_bits (const real_t *used_coeff, const word_t *used_states,
+	  unsigned level, const coeff_t *coeff);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+typedef struct c_array
+{
+   const char *identifier;
+   coeff_t    *(*function) (rpf_t *rpf, rpf_t *dc_rpf,
+			    unsigned min_level, unsigned max_level);
+} c_array_t;
+
+c_array_t coeff_models[] = {{"adaptive", alloc_aac_coeff_model},
+			    {"uniform",	 alloc_uniform_coeff_model},
+			    {NULL,	 NULL}};
+
+coeff_t *
+alloc_coeff_model (const char *coeff_model_name, rpf_t *rpf, rpf_t *dc_rpf,
+		   unsigned min_level, unsigned max_level)
+/*
+ *  Allocate a new coefficients model which is identified by the string
+ *  'coeff_model_name'.  'rpf' and 'dc_rpf' define the reduced
+ *  precision formats the should be used to quantize normal and DC
+ *  components, respectively. 'min_level' and 'max_level' define the
+ *  range of range approximations.
+ * 
+ *  Return value:
+ *	pointer to the allocated coefficients model
+ *
+ *  Note:
+ *      Refer to 'coeff.h' for a short description of the member functions.  */
+{
+   unsigned n;
+   
+   for (n = 0; coeff_models [n].identifier; n++) /* step through all id's */
+      if (strcaseeq (coeff_models [n].identifier, coeff_model_name)) 
+	 return coeff_models [n].function (rpf, dc_rpf, min_level, max_level);
+
+   warning ("Can't initialize coefficients model '%s'. "
+	    "Using default value '%s'.",
+	    coeff_model_name, coeff_models [0].identifier);
+
+   return coeff_models [0].function (rpf, dc_rpf, min_level, max_level);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+/*****************************************************************************
+		  uniform distribution coefficients model
+*****************************************************************************/
+
+static coeff_t *
+alloc_uniform_coeff_model (rpf_t *rpf, rpf_t *dc_rpf,
+			   unsigned min_level, unsigned max_level)
+/*
+ *  Underlying probability model: uniform distribution.
+ *  I.e. each coefficient is written as such with
+ *  (1 + exponent_bits + mantissa_bits) bits.
+ */
+{
+   coeff_t *coeff = default_alloc (rpf, dc_rpf, min_level, max_level);
+
+   coeff->bits   = uniform_bits;
+   coeff->update = uniform_update;
+   
+   return coeff;
+}
+
+static real_t
+uniform_bits (const real_t *used_coeff, const word_t *used_states,
+	      unsigned level, const coeff_t *coeff)
+{
+   unsigned edge;
+   real_t   bits = 0;			/* #bits to store coefficients */
+   
+   for (edge = 0; isedge (used_states [edge]); edge++)
+   {
+      rpf_t *rpf = used_states [edge] ? coeff->rpf : coeff->dc_rpf;
+      
+      bits += rpf->mantissa_bits + 1;
+   }
+
+   return bits;
+}
+
+static void
+uniform_update (const real_t *used_coeff, const word_t *used_states,
+		unsigned level, coeff_t *coeff)
+{
+   return;				/* nothing to do */
+}
+
+/*****************************************************************************
+		adaptive arithmetic coding  model
+*****************************************************************************/
+
+typedef struct aac_model
+{
+   word_t *counts;
+   word_t *totals;
+} aac_model_t;
+
+static coeff_t *
+alloc_aac_coeff_model (rpf_t *rpf, rpf_t *dc_rpf,
+		       unsigned min_level, unsigned max_level)
+/*
+ *  Underlying probability model: adaptive arithmetic coding using
+ *  the level of a range as context.
+ */
+{
+   coeff_t *coeff = default_alloc (rpf, dc_rpf, min_level, max_level);
+   
+   coeff->bits            = aac_bits;
+   coeff->update          = aac_update;
+   coeff->model_free      = aac_model_free;
+   coeff->model_duplicate = aac_model_duplicate;
+   coeff->model		  = aac_model_alloc (coeff);
+   
+   return coeff;
+}
+
+static real_t
+aac_bits (const real_t *used_coeff, const word_t *used_states,
+	  unsigned level, const coeff_t *coeff)
+{
+   real_t	bits  = 0;		/* # bits to store coefficients */
+   unsigned	edge;
+   int		state;
+   word_t      *counts;
+   aac_model_t *model = (aac_model_t *) coeff->model;
+
+   counts = model->counts
+	    + (1 << (1 + coeff->dc_rpf->mantissa_bits))
+	    + ((level - coeff->min_level)
+	       * (1 << (1 + coeff->rpf->mantissa_bits)));
+   
+   for (edge = 0; isedge (state = used_states [edge]); edge++)
+      if (state)
+	 bits -= log2 (counts [rtob (used_coeff [edge], coeff->rpf)]
+		       / (real_t) model->totals [level
+						- coeff->min_level + 1]);
+      else
+	 bits -= log2 (model->counts [rtob (used_coeff [edge], coeff->dc_rpf)]
+		       / (real_t) model->totals [0]);
+   
+   return bits;
+}
+
+static void
+aac_update (const real_t *used_coeff, const word_t *used_states,
+	    unsigned level, coeff_t *coeff)
+{
+   unsigned	edge;
+   int		state;
+   word_t      *counts;
+   aac_model_t *model = (aac_model_t *) coeff->model;
+
+   counts = model->counts
+	    + (1 << (1 + coeff->dc_rpf->mantissa_bits))
+	    + ((level - coeff->min_level)
+	       * (1 << (1 + coeff->rpf->mantissa_bits)));
+
+   for (edge = 0; isedge (state = used_states [edge]); edge++)
+      if (state)
+      {
+	 counts [rtob (used_coeff [edge], coeff->rpf)]++;
+	 model->totals [level - coeff->min_level + 1]++;
+      }
+      else
+      {
+	 model->counts [rtob (used_coeff [edge], coeff->dc_rpf)]++;
+	 model->totals [0]++;
+      }
+}
+
+static void *
+aac_model_duplicate (const coeff_t *coeff, const void *model)
+{
+   aac_model_t *src = (aac_model_t *) model;
+   aac_model_t *dst = aac_model_alloc (coeff);
+
+   memcpy (dst->counts, src->counts,
+	   sizeof (word_t) * ((coeff->max_level - coeff->min_level + 1)
+			      * (1 << (1 + coeff->rpf->mantissa_bits))
+			      + (1 << (1 + coeff->dc_rpf->mantissa_bits))));
+   memcpy (dst->totals, src->totals,
+	   sizeof (word_t) * (coeff->max_level - coeff->min_level + 1 + 1));
+   
+   return dst;
+}
+
+static void *
+aac_model_alloc (const coeff_t *coeff)
+{
+   aac_model_t *model;
+   unsigned	size = (coeff->max_level - coeff->min_level + 1)
+		       * (1 << (1 + coeff->rpf->mantissa_bits))
+		       + (1 << (1 + coeff->dc_rpf->mantissa_bits));
+   
+   model 	 = Calloc (1, sizeof (aac_model_t));
+   model->counts = Calloc (size, sizeof (word_t));
+   model->totals = Calloc (coeff->max_level - coeff->min_level + 1 + 1,
+			   sizeof (word_t));
+   /*
+    *  Initialize model
+    */
+   {
+      unsigned  n;
+      word_t   *ptr = model->counts;
+      
+      for (n = size; n; n--)
+	 *ptr++ = 1;
+      model->totals [0] = 1 << (1 + coeff->dc_rpf->mantissa_bits);
+      for (n = coeff->min_level; n <= coeff->max_level; n++)
+	 model->totals [n - coeff->min_level + 1]
+	    = 1 << (1 + coeff->rpf->mantissa_bits);
+   }
+   
+   return (void *) model;
+}
+
+static void
+aac_model_free (void *model)
+{
+   aac_model_t	*aac_model = (aac_model_t *) model;
+
+   if (aac_model)
+   {
+      Free (aac_model->counts);
+      Free (aac_model->totals);
+      Free (aac_model);
+   }
+}
+
+/*****************************************************************************
+				default functions
+*****************************************************************************/
+
+static coeff_t *
+default_alloc (rpf_t *rpf, rpf_t *dc_rpf,
+	       unsigned min_level, unsigned max_level)
+{
+   coeff_t *coeff = Calloc (1, sizeof (coeff_t));
+
+   coeff->rpf 	      	  = rpf;
+   coeff->dc_rpf       	  = dc_rpf;
+   coeff->min_level	  = min_level;
+   coeff->max_level	  = max_level;
+   coeff->model	      	  = NULL;
+   coeff->bits	      	  = NULL;
+   coeff->update      	  = NULL;
+   coeff->free	      	  = default_free;
+   coeff->model_free  	  = default_model_free;
+   coeff->model_duplicate = default_model_duplicate;
+   
+   return coeff;
+}
+
+static void
+default_free (coeff_t *coeff)
+{
+   coeff->model_free (coeff->model);
+   Free (coeff);
+}
+
+static void *
+default_model_duplicate (const coeff_t *coeff, const void *model)
+{
+   return NULL;
+}
+
+static void
+default_model_free (void *model)
+{
+   if (model)
+      Free (model);
+}
diff --git a/converter/other/fiasco/codec/coeff.h b/converter/other/fiasco/codec/coeff.h
new file mode 100644
index 00000000..118cd0fc
--- /dev/null
+++ b/converter/other/fiasco/codec/coeff.h
@@ -0,0 +1,61 @@
+/*
+ *  coeff.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _COEFF_H
+#define _COEFF_H
+
+#include "types.h"
+#include "rpf.h"
+#include "wfa.h"
+
+typedef struct coeff
+{
+   rpf_t    *rpf;			/* reduced precision format */
+   rpf_t    *dc_rpf;			/* RPF of DC (state 0) component */
+   unsigned min_level, max_level;	/* allocate memory for [min,..,max] */
+   void	    *model;			/* generic pointer to prob. model */
+   real_t (*bits) (const real_t *used_coeff, const word_t *used_domains,
+		   unsigned level, const struct coeff *coeff);
+   /*
+    *  Compute bit-rate of a range approximation with coefficients given by
+    *  -1 terminated list 'used_domains'.
+    */
+   void   (*update) (const real_t *used_coeff, const word_t *used_domains,
+		       unsigned level, struct coeff *coeff);
+   /*
+    *  Update the probability model according to the chosen approximation.
+    *  (given by the -1 terminated list 'used_domains').
+    */
+   void	  (*free) (struct coeff *coeff);
+   /*
+    *  Discard the given coefficients struct.
+    */
+   void   (*model_free) (void *model);
+   /*
+    *  Free given probability model.
+    */
+   void   *(*model_duplicate) (const struct coeff *coeff, const void *model);
+   /*
+    *  Duplicate the given probability model (i.e. alloc and copy).
+    */
+} coeff_t;
+
+coeff_t *
+alloc_coeff_model (const char *coeff_model_name, rpf_t *rpf, rpf_t *dc_rpf,
+		   unsigned min_level, unsigned max_level);
+
+#endif /* not _COEFF_H */
+
diff --git a/converter/other/fiasco/codec/control.c b/converter/other/fiasco/codec/control.c
new file mode 100644
index 00000000..9af9928b
--- /dev/null
+++ b/converter/other/fiasco/codec/control.c
@@ -0,0 +1,276 @@
+/*
+ *  control.c:		Control unit of WFA structure
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+ 
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "cwfa.h"
+#include "ip.h"
+#include "misc.h"
+#include "wfalib.h"
+#include "control.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void 
+clear_or_alloc (real_t **ptr, size_t size);
+static void 
+compute_images (unsigned from, unsigned to, const wfa_t *wfa, coding_t *c);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void    
+append_state (bool_t auxiliary_state, real_t final, unsigned level_of_state,
+	      wfa_t *wfa, coding_t *c)
+/*
+ *  Append a 'wfa' state. If 'auxiliary_state' == YES then
+ *  allocate memory for inner products and state images.  'final' is
+ *  the final distribution of the new state. 'level_of_state' is the
+ *  level of the subimage which is represented by this state
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	The WFA information are updated in structure 'wfa'
+ *	State images are computed and inner products are cleared (in 'c')
+ */
+{
+   wfa->final_distribution [wfa->states] = final;
+   wfa->level_of_state [wfa->states]     = level_of_state;
+   
+   if (!auxiliary_state)
+   {
+      unsigned level;
+
+      wfa->domain_type [wfa->states] = USE_DOMAIN_MASK;
+
+      /*
+       *  Allocate memory for inner products and for state images
+       */
+      clear_or_alloc (&c->images_of_state [wfa->states],
+		      size_of_tree (c->options.images_level));
+	 
+      for (level = c->options.images_level + 1;
+	   level <= c->options.lc_max_level; level++)
+	 clear_or_alloc (&c->ip_states_state [wfa->states][level],
+			 wfa->states + 1);
+
+      clear_or_alloc (&c->ip_images_state [wfa->states],
+		      size_of_tree (c->products_level));
+
+      /*
+       *  Compute the images of the current state at level 0,..,'imageslevel'
+       */
+      
+      c->images_of_state [wfa->states][0] = final;
+      compute_images (wfa->states, wfa->states, wfa, c);  
+
+      /*
+       *  Compute the inner products between the current state and the
+       *  old states 0,...,'states'-1
+       */ 
+      
+      compute_ip_states_state (wfa->states, wfa->states, wfa, c);
+   }
+   else
+   {
+      unsigned level;
+      
+      wfa->domain_type [wfa->states] = 0;
+	    
+      /*
+       *  Free the allocated memory
+       */
+      if (c->images_of_state [wfa->states] != NULL)
+      {
+	 Free (c->images_of_state [wfa->states]);
+	 c->images_of_state [wfa->states] = NULL;
+      }
+      for (level = 0; level <= c->options.lc_max_level; level++)
+	 if (c->ip_states_state [wfa->states][level])
+	 {
+	    Free (c->ip_states_state [wfa->states][level]);
+	    c->ip_states_state [wfa->states][level] = NULL;
+	 }
+      if (c->ip_images_state [wfa->states])
+      {
+	 Free (c->ip_images_state [wfa->states]);
+	 c->ip_images_state [wfa->states] = NULL;
+      }
+   }
+   
+   wfa->states++;
+   if (wfa->states >= MAXSTATES) 
+      error ("Maximum number of states reached!");
+}	
+ 
+void 
+append_basis_states (unsigned basis_states, wfa_t *wfa, coding_t *c)
+/*
+ *  Append the WFA basis states 0, ... , ('basis_states' - 1).
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	The WFA information are updated in structure 'wfa'
+ *	State images and inner products are computed (in 'c')
+ */
+{
+   unsigned level, state;
+
+   /*
+    *  Allocate memory
+    */
+
+   for (state = 0; state < basis_states; state++)
+   {
+      clear_or_alloc (&c->images_of_state [state],
+		      size_of_tree (c->options.images_level));
+
+      for (level = c->options.images_level + 1;
+	   level <= c->options.lc_max_level; level++)
+	 clear_or_alloc (&c->ip_states_state [state][level], state + 1);
+
+      clear_or_alloc (&c->ip_images_state [state],
+		      size_of_tree (c->products_level));
+
+      c->images_of_state [state][0] = wfa->final_distribution [state];
+      wfa->level_of_state [state]   = -1;
+   }
+   
+   compute_images (0, basis_states - 1, wfa, c);  
+   compute_ip_states_state (0, basis_states - 1, wfa, c);
+   wfa->states = basis_states;
+   
+   if (wfa->states >= MAXSTATES) 
+      error ("Maximum number of states reached!");
+}	
+ 
+void 
+append_transitions (unsigned state, unsigned label, const real_t *weight,
+		    const word_t *into, wfa_t *wfa)
+/*
+ *  Append the 'wfa' transitions (given by the arrays 'weight' and 'into')
+ *  of the range ('state','label').
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	new 'wfa' edges are appended
+ */
+{
+   unsigned edge;
+
+   wfa->y_column [state][label] = 0;
+   for (edge = 0; isedge (into [edge]); edge++)
+   {
+      append_edge (state, into [edge], weight [edge], label, wfa);
+      if (into [edge] == wfa->y_state [state][label])
+	 wfa->y_column [state][label] = 1;
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void 
+compute_images (unsigned from, unsigned to, const wfa_t *wfa, coding_t *c)
+/*
+ *  Computes the images of the given states 'from', ... , 'to' 
+ *  at level 0,...,'c->imagelevel'.
+ *  Uses the fact that each state image is a linear combination of state
+ *  images, i.e. s_i := c_0 s_0 + ... + c_i s_i.
+ */
+{
+   unsigned label, level, state;
+   
+   /*
+    *  Compute the images Phi(state)
+    *  #		level = 0
+    *  ##		level = 1
+    *  ####		level = 2
+    *  ########    	level = 3
+    *  ...
+    *  ########...##    level = imageslevel
+    */
+   
+   for (level = 1; level <= c->options.images_level; level++)
+      for (state = from; state <= to; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	 {
+	    real_t   *dst, *src;
+	    unsigned  edge;
+	    int	      domain;		/* current domain */
+	    
+	    if (ischild (domain = wfa->tree[state][label]))
+	    {
+	       dst = c->images_of_state [state] + address_of_level (level) +
+		     label * size_of_level (level - 1);
+	       src = c->images_of_state [domain]
+		     + address_of_level (level - 1);
+	       memcpy (dst, src, size_of_level (level - 1) * sizeof (real_t));
+	    }
+	    for (edge = 0; isedge (domain = wfa->into[state][label][edge]);
+		 edge++)
+	    {
+	       unsigned n;
+	       real_t 	weight = wfa->weight [state][label][edge];
+	       
+	       dst = c->images_of_state [state] + address_of_level (level) +
+		     label * size_of_level (level - 1);
+	       src = c->images_of_state [domain]
+		     + address_of_level (level - 1);
+		  
+	       for (n = size_of_level (level - 1); n; n--)
+		  *dst++ += *src++ * weight;
+	    }
+	 }
+
+}
+
+static void 
+clear_or_alloc (real_t **ptr, size_t size)
+/*
+ *  if *ptr == NULL 	allocate memory with Calloc 
+ *  otherwise 		fill the real_t-array ptr[] with 0
+ */
+{
+   if (*ptr == NULL) 
+      *ptr = Calloc (size, sizeof (real_t));
+   else 
+      memset (*ptr, 0, size * sizeof (real_t));
+    
+}
diff --git a/converter/other/fiasco/codec/control.h b/converter/other/fiasco/codec/control.h
new file mode 100644
index 00000000..f601d8b8
--- /dev/null
+++ b/converter/other/fiasco/codec/control.h
@@ -0,0 +1,33 @@
+/*
+ *  control.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _CONTROL_H
+#define _CONTROL_H
+
+#include "cwfa.h"
+#include "types.h"
+
+void 
+append_transitions (unsigned state, unsigned label, const real_t *weight,
+		    const word_t *into, wfa_t *wfa);
+void 
+append_basis_states (unsigned basis_states, wfa_t *wfa, coding_t *c);
+void    
+append_state (bool_t auxiliary_state, real_t final, unsigned level_of_state,
+	      wfa_t *wfa, coding_t *c);
+
+#endif /* not _CONTROL_H */
+
diff --git a/converter/other/fiasco/codec/cwfa.h b/converter/other/fiasco/codec/cwfa.h
new file mode 100644
index 00000000..9c4e7fee
--- /dev/null
+++ b/converter/other/fiasco/codec/cwfa.h
@@ -0,0 +1,107 @@
+/*
+ *  cwfa.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/10/28 17:39:30 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#ifndef _CWFA_H
+#define _CWFA_H
+
+#include "wfa.h"
+#include "types.h"
+#include "tiling.h"
+#include "rpf.h"
+#include "domain-pool.h"
+#include "bintree.h"
+#include "coeff.h"
+#include "list.h"
+#include "wfalib.h"
+#include "options.h"
+
+extern const real_t MAXCOSTS;
+
+typedef struct motion
+{
+   image_t	 *original;		/* Current image */
+   image_t	 *past;			/* Preceeding image */
+   image_t	 *future;		/* Succeeding image */
+   frame_type_e	  frame_type;		/* frame type: B_, P_ I_FRAME */
+   unsigned	  number;		/* display number of frame */
+   real_t        *xbits;		/* # bits for mv x-component */
+   real_t        *ybits;		/* # bits for mv y-component */
+   real_t       **mc_forward_norms; 	/* norms of mcpe */
+   real_t       **mc_backward_norms; 	/* norms of mcpe */
+} motion_t;
+
+typedef struct range
+/*
+ *  Information about current range in the original image.
+ *  Approximation data (error, encoding bits, approximation type and factors
+ *  of the linear combination) are also saved.
+ */ 
+{
+   unsigned global_address;             /* We need absolute image addresses
+				           for distance calculations. */
+   unsigned x, y;			/* Coordinates of upper left corner */
+   unsigned image;			/* Position in the tree */
+   unsigned address;			/* Address of the pixel data */
+   unsigned level;			/* Level of the range */
+   real_t   weight [MAXEDGES + 1];	/* coeff. of the approximation */
+   word_t   into [MAXEDGES + 1];	/* used domains of the approximation */
+   int	    tree;			/* == domain : range is approximated
+					   with new state 'domain'
+					   == RANGE  :
+					   with a linear comb. */
+   real_t   err;			/* approximation error */
+   real_t   tree_bits;			/* # bits to encode tree */
+   real_t   matrix_bits;		/* # bits to encode matrices */
+   real_t   weights_bits;		/* # bits to encode weights */
+   mv_t	    mv;				/* motion vector */
+   real_t   mv_tree_bits;		/* # bits to encode mv tree */
+   real_t   mv_coord_bits;		/* # bits to encode mv coordinates */
+   real_t   nd_tree_bits;		/* # bits to encode nd tree */
+   real_t   nd_weights_bits;		/* # bits to encode nd factors */
+   bool_t   prediction;			/* range is predicted? */
+} range_t;
+
+typedef struct coding
+/*
+ *  All parameters and variables that must be accessible through the coding
+ *  process.
+ */
+{
+   real_t     	   price;		/* determines quality of approx. */
+   real_t   	 **images_of_state;	/* image of state i at level
+					   0, ... , imageslevel */
+   real_t   *(*ip_states_state)[MAXLEVEL]; /* inner products between state i
+					      and states 0, ... , i
+					      at all image levels */
+   real_t   	 **ip_images_state;	/* inner products between all
+					   ranges and state i */
+   real_t    	  *pixels;		/* current image pixels stored in tree
+					   order (only leaves are stored) */
+   unsigned   	   products_level;	/* inner products are stored up to
+					   this level */
+   tiling_t   	  *tiling;		/* tiling of the entire image */
+   tree_t     	   tree;		/* probability model */
+   tree_t     	   p_tree;		/* prediction probability model */
+   motion_t   	  *mt;			/* motion compensation information */
+   coeff_t   	  *coeff;
+   coeff_t   	  *d_coeff;
+   domain_pool_t  *domain_pool;
+   domain_pool_t  *d_domain_pool;
+   c_options_t     options;		/* global options */
+} coding_t;
+
+#endif /* not _CWFA_H */
+
diff --git a/converter/other/fiasco/codec/decoder.c b/converter/other/fiasco/codec/decoder.c
new file mode 100644
index 00000000..9474c1e7
--- /dev/null
+++ b/converter/other/fiasco/codec/decoder.c
@@ -0,0 +1,1532 @@
+/*
+ *  decode.c:		Decoding of an image represented by a WFA
+ *
+ *  Written by:		Ullrich Hafner
+ *			Michael Unger
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+ 
+/*
+ *  $Date: 2000/10/22 10:44:48 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "image.h"
+#include "misc.h"
+#include "motion.h"
+#include "read.h"
+#include "wfalib.h"
+#include "decoder.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+compute_state_images (unsigned frame_level, word_t **simg,
+		      const u_word_t *offset, const wfa_t *wfa);
+static void
+free_state_images (unsigned max_level, bool_t color, word_t **state_image,
+		   u_word_t *offset, const unsigned *root_state,
+		   unsigned range_state, format_e format, const wfa_t *wfa);
+static void
+alloc_state_images (word_t ***images, u_word_t **offsets, const image_t *frame,
+		    const unsigned *root_state, unsigned range_state,
+		    unsigned max_level, format_e format, const wfa_t *wfa);
+static void
+compute_actual_size (unsigned luminance_root,
+		     unsigned *width, unsigned *height, const wfa_t *wfa);
+static void
+enlarge_image (int enlarge_factor, format_e format, unsigned y_root,
+	       wfa_t *wfa);
+static word_t *
+duplicate_state_image (const word_t *domain, unsigned offset, unsigned level);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+video_t *
+alloc_video (bool_t store_wfa)
+/*
+ *  Video struct constructor:
+ *  Initialize video structure and allocate memory for current, past
+ *  and future WFA if flag 'store_wfa' is TRUE.
+ *
+ *  Return value:
+ *	pointer to the new video structure
+ */
+{
+   video_t *video = Calloc (1, sizeof (video_t));
+   
+   video->future_display = -1;
+   video->display        = 0;
+
+   video->future = video->sfuture = video->past
+		 = video->frame   = video->sframe = NULL;
+
+   if (store_wfa)
+   {
+      video->wfa        = alloc_wfa (NO);
+      video->wfa_past   = alloc_wfa (NO);
+      video->wfa_future = alloc_wfa (NO);
+   }
+   else
+      video->wfa = video->wfa_past = video->wfa_future = NULL;
+
+   return video;
+}
+
+void
+free_video (video_t *video)
+/*
+ *  Video struct destructor:
+ *  Free memory of given 'video' struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'video' struct is discarded.
+ */
+{
+   if (video->past)
+      free_image (video->past);
+   if (video->future)
+      free_image (video->future);
+   if (video->sfuture)
+      free_image (video->sfuture);
+   if (video->frame)
+      free_image (video->frame);
+   if (video->sframe)
+      free_image (video->sframe);
+   if (video->wfa)
+      free_wfa (video->wfa);
+   if (video->wfa_past)
+      free_wfa (video->wfa_past);
+   if (video->wfa_future)
+      free_wfa (video->wfa_future);
+
+   Free (video);
+}
+
+image_t *
+get_next_frame (bool_t store_wfa, int enlarge_factor,
+		int smoothing, const char *reference_frame,
+		format_e format, video_t *video, dectimer_t *timer,
+		wfa_t *orig_wfa, bitfile_t *input)
+/*
+ *  Get next frame of the WFA 'video' from stream 'input'.
+ *  'orig_wfa' is the constant part of the WFA used by all frames.
+ *  Depending on values of 'enlarge_factor' and 'smoothing' enlarge and
+ *  smooth image, respectively. 
+ *  If 'store_wfa' is TRUE, then store WFA structure of reference frames
+ *  (used by analysis tool xwfa).
+ *  If 'reference_frame' is not NULL, then load image 'reference_frame'
+ *  from disk.
+ *  'format' gives the color format to be used (either 4:2:0 or 4:4:4).
+ *  If 'timer' is not NULL, then accumulate running time statistics. 
+ *
+ *  Return value:
+ *	pointer to decoded frame
+ *
+ *  Side effects:
+ *	'video' and 'timer' struct are modified.
+ */
+{
+   image_t *frame 			  = NULL; /* current frame */
+   image_t *sframe 			  = NULL; /* current smoothed frame */
+   bool_t   current_frame_is_future_frame = NO;
+
+   if (video->future_display == video->display)	 
+   {
+      /*
+       *  Future frame is already computed since it has been used
+       *  as reference frame. So just return the stored frame.
+       */
+      if (video->frame) /* discard current frame */
+	 free_image (video->frame);
+      video->frame  = video->future;
+      video->future = NULL;
+
+      if (video->sframe) /* discard current (smoothed) frame */
+	 free_image (video->sframe);
+      video->sframe  = video->sfuture;
+      video->sfuture = NULL;
+
+      if (store_wfa)
+	 copy_wfa (video->wfa, video->wfa_future);
+
+      video->display++;
+
+      if (!store_wfa)
+	 video->wfa = NULL;
+   }
+   else
+   {
+      do				/* compute next frame(s) */
+      {
+	 unsigned      frame_number;	/* current frame number */
+	 clock_t       ptimer;
+	 unsigned int  stop_timer [3];
+	 wfa_t	      *tmp_wfa = NULL;
+	 
+	 if (!store_wfa)
+	    video->wfa = orig_wfa;
+	 else
+	 {
+	    tmp_wfa = alloc_wfa (NO);
+	    copy_wfa (tmp_wfa, video->wfa);
+	    copy_wfa (video->wfa, orig_wfa);
+	 }
+   
+	 /*
+	  *  First step: read WFA from disk
+	  */
+	 prg_timer (&ptimer, START);
+	 frame_number = read_next_wfa (video->wfa, input);
+	 stop_timer [0] = prg_timer (&ptimer, STOP);
+	 if (timer)
+	 {
+	    timer->input [video->wfa->frame_type] += stop_timer [0];
+	    timer->frames [video->wfa->frame_type]++;
+	 }
+      
+	 /*
+	  *  Read reference frame from disk if required
+	  *  (i.e., 1st frame is of type B or P)
+	  */
+	 if (video->display == 0 && video->wfa->frame_type != I_FRAME)
+	 {
+	    if (!reference_frame)
+	       error ("First frame is %c-frame but no "
+		      "reference frame is given.",
+		      video->wfa->frame_type == B_FRAME ? 'B' : 'P');
+
+	    video->frame  = read_image (reference_frame);
+	    video->sframe = NULL;
+	 }
+   
+	 /*
+	  *  Depending on current frame type update past and future frames
+	  */
+	 if (video->wfa->frame_type == I_FRAME)
+	 {
+	    if (video->past)		/* discard past frame */
+	       free_image (video->past);
+	    video->past = NULL;
+	    if (video->future)		/* discard future frame */
+	       free_image (video->future);
+	    video->future = NULL;
+	    if (video->sfuture)		/* discard (smoothed) future frame */
+	       free_image (video->sfuture);
+	    video->sfuture = NULL;
+	    if (video->frame)		/* discard current frame */
+	       free_image (video->frame);
+	    video->frame = NULL;
+	    if (video->sframe)		/* discard current (smoothed) frame */
+	       free_image (video->sframe);
+	    video->sframe = NULL;
+	 }
+	 else if (video->wfa->frame_type == P_FRAME)
+	 {
+	    if (video->past)		/* discard past frame */
+	       free_image (video->past);
+	    video->past = video->frame;	/* past <- current frame */
+	    video->frame = NULL;
+	    if (video->sframe)		/* discard current (smoothed) frame */
+	       free_image (video->sframe);
+	    video->sframe = NULL;
+	    if (store_wfa)
+	       copy_wfa (video->wfa_past, tmp_wfa);
+	    if (video->future)		/* discard future frame */
+	       free_image (video->future);
+	    video->future = NULL;
+	    if (video->sfuture)		/* discard (smoothed) future frame */
+	       free_image (video->sfuture);
+	    video->sfuture = NULL;
+	 }
+	 else				/* B_FRAME */
+	 {
+	    if (current_frame_is_future_frame)
+	    {
+	       if (video->future)	/* discard future frame */
+		  free_image (video->future);
+	       video->future = frame;	/* future <- current frame */
+	       if (video->sfuture)	/* discard (smoothed) future frame */
+		  free_image (video->sfuture);
+	       video->sfuture = sframe;	/* future <- current (smoothed) */
+	       if (store_wfa)
+		  copy_wfa (video->wfa_future, tmp_wfa);
+	       if (video->frame)	/* discard current frame */
+		  free_image (video->frame);
+	       video->frame = NULL;
+	       if (video->sframe)	/* discard current (smoothed) frame */
+		  free_image (video->sframe);
+	       video->sframe = NULL;
+	       frame  = NULL;
+	       sframe = NULL;
+	    }
+	    else
+	    {
+	       if (video->wfa->wfainfo->B_as_past_ref == YES)
+	       {
+		  if (video->past)	/* discard past frame */
+		     free_image (video->past);
+		  video->past  = video->frame; /* past <- current frame */
+		  video->frame = NULL;
+		  if (video->sframe)	/* discard current (smoothed) frame */
+		     free_image (video->sframe);
+		  video->sframe = NULL;
+		  if (store_wfa)
+		     copy_wfa (video->wfa_past, tmp_wfa);
+	       }
+	       else
+	       {
+		  if (video->frame)	/* discard current */
+		     free_image (video->frame);
+		  video->frame = NULL;
+		  if (video->sframe)	/* discard current (smoothed) frame */
+		     free_image (video->sframe);
+		  video->sframe = NULL;
+	       }
+	    }
+	 }
+	 if (tmp_wfa)
+	    free_wfa (tmp_wfa);
+	 
+	 current_frame_is_future_frame = NO;
+	 /*
+	  *  Second step: decode image
+	  *  Optionally enlarge image if specified by option 'enlarge_factor'.
+	  */
+	 {
+	    unsigned orig_width, orig_height;
+
+	    stop_timer [0] = stop_timer [1] = stop_timer [2] = 0;
+	 
+	    enlarge_image (enlarge_factor, format,
+			   (video->wfa->wfainfo->color
+			    && format == FORMAT_4_2_0)
+			   ? video->wfa->tree [video->wfa->tree [video->wfa->root_state][0]][0] : -1, video->wfa);
+
+	    if (enlarge_factor > 0)
+	    {
+	       orig_width  = video->wfa->wfainfo->width  << enlarge_factor;
+	       orig_height = video->wfa->wfainfo->height << enlarge_factor; 
+	    }
+	    else
+	    { 
+	       orig_width  = video->wfa->wfainfo->width  >> - enlarge_factor;
+	       orig_height = video->wfa->wfainfo->height >> - enlarge_factor;
+	       if (orig_width & 1)
+		  orig_width++;
+	       if (orig_height & 1)
+		  orig_height++;
+	    }
+	 
+	    frame = decode_image (orig_width, orig_height, format,
+				  timer != NULL ? stop_timer : NULL,
+				  video->wfa);
+	    if (timer)
+	    {
+	       timer->preprocessing [video->wfa->frame_type] += stop_timer [0];
+	       timer->decoder [video->wfa->frame_type]       += stop_timer [1];
+	       timer->cleanup [video->wfa->frame_type]       += stop_timer [2];
+	    }
+	 }
+
+	 /*
+	  *  Third step: restore motion compensation
+	  */
+	 if (video->wfa->frame_type != I_FRAME)
+	 {
+	    prg_timer (&ptimer, START);
+	    restore_mc (enlarge_factor, frame, video->past, video->future,
+			video->wfa);
+	    stop_timer [0] = prg_timer (&ptimer, STOP);
+	    if (timer)
+	       timer->motion [video->wfa->frame_type] += stop_timer [0];
+	 }
+
+	 /*
+	  *  Fourth step: smooth image along partitioning borders
+	  */
+	 prg_timer (&ptimer, START);
+	 if (smoothing < 0)	/* smoothing not changed by user */
+	    smoothing = video->wfa->wfainfo->smoothing;
+	 if (smoothing > 0 && smoothing <= 100)
+	 {
+	    sframe = clone_image (frame);
+	    smooth_image (smoothing, video->wfa, sframe);
+	 }
+	 else
+	    sframe = NULL;
+	 
+	 stop_timer [0] = prg_timer (&ptimer, STOP);
+	 if (timer)
+	    timer->smooth [video->wfa->frame_type] += stop_timer [0];
+
+	 if (frame_number == video->display)
+	 {
+	    video->display++;
+	    video->frame  = frame;
+	    video->sframe = sframe;
+	    frame         = NULL;
+	    sframe        = NULL;
+	 }
+	 else if (frame_number > video->display)
+	 {
+	    video->future_display 	  = frame_number;
+	    current_frame_is_future_frame = YES;
+	 }
+      
+	 if (!store_wfa)
+	    remove_states (video->wfa->basis_states, video->wfa);
+      } while (!video->frame);
+
+      if (!store_wfa)
+	 video->wfa = NULL;
+   }
+   
+   return video->sframe ? video->sframe : video->frame;
+}
+
+image_t *
+decode_image (unsigned orig_width, unsigned orig_height, format_e format,
+	      unsigned *dec_timer, const wfa_t *wfa)
+/*
+ *  Compute image which is represented by the given 'wfa'.
+ *  'orig_width'x'orig_height' gives the resolution of the image at
+ *  coding time. Use 4:2:0 subsampling or 4:4:4 'format' for color images.
+ *  If 'dec_timer' is given, accumulate running time statistics. 
+ *  
+ *  Return value:
+ *	pointer to decoded image
+ *
+ *  Side effects:
+ *	'*dectimer' is changed if 'dectimer' != NULL.
+ */
+{
+   unsigned   root_state [3];		/* root of bintree for each band */
+   unsigned   width, height;		/* computed image size */
+   image_t   *frame;			/* regenerated frame */
+   word_t   **images;			/* pointer to array of pointers
+					   to state images */
+   u_word_t  *offsets;			/* pointer to array of state image
+					   offsets */
+   unsigned   max_level;		/* max. level of state with approx. */
+   unsigned   state;
+   clock_t    ptimer;
+
+   prg_timer (&ptimer, START);
+
+   /*
+    *  Compute root of bintree for each color band
+    */
+   if (wfa->wfainfo->color)
+   {
+      root_state [Y]  = wfa->tree [wfa->tree [wfa->root_state][0]][0];
+      root_state [Cb] = wfa->tree [wfa->tree [wfa->root_state][0]][1];
+      root_state [Cr] = wfa->tree [wfa->tree [wfa->root_state][1]][0];
+   }
+   else
+      root_state [GRAY] = wfa->root_state;
+
+   /*
+    *  Compute maximum level of a linear combination
+    */
+   for (max_level = 0, state = wfa->basis_states; state < wfa->states; state++)
+      if (isedge (wfa->into [state][0][0]) || isedge (wfa->into [state][1][0]))
+	 max_level = max (max_level, wfa->level_of_state [state]);
+   
+
+   /*
+    *  Allocate frame buffer for decoded image
+    */
+   compute_actual_size (format == FORMAT_4_2_0 ? root_state [Y] : MAXSTATES,
+			&width, &height, wfa);
+   width  = max (width, orig_width);
+   height = max (height, orig_height);
+   frame = alloc_image (width, height, wfa->wfainfo->color, format);
+   
+   /*
+    *  Allocate buffers for intermediate state images
+    */
+   if (wfa->wfainfo->color)
+   {
+      wfa->level_of_state [wfa->root_state]               = 128;
+      wfa->level_of_state [wfa->tree[wfa->root_state][0]] = 128;
+      wfa->level_of_state [wfa->tree[wfa->root_state][1]] = 128;
+   }
+   alloc_state_images (&images, &offsets, frame, root_state, 0, max_level, 
+		       format, wfa);
+
+   if (dec_timer)
+      dec_timer [0] += prg_timer (&ptimer, STOP);
+
+   /*
+    *  Decode all state images, forming the complete image.
+    */
+   prg_timer (&ptimer, START);
+   compute_state_images (max_level, images, offsets, wfa);
+   if (dec_timer)
+      dec_timer [1] += prg_timer (&ptimer, STOP);
+
+   /*
+    *  Cleanup buffers used for intermediate state images
+    */
+   prg_timer (&ptimer, START);
+   free_state_images (max_level, frame->color, images, offsets, root_state, 0,
+		      format, wfa);
+   
+   /*
+    *  Crop decoded image if the image size differs.
+    */
+   if (orig_width != width || orig_height != height)
+   {
+      frame->height = orig_height;	
+      frame->width  = orig_width;	
+      if (orig_width != width)		
+      {
+	 color_e   band;		/* current color band */
+	 word_t	  *src, *dst;		/* source and destination pointers */
+	 unsigned  y;			/* current row */
+	 
+	 for (band  = first_band (frame->color);
+	      band <= last_band (frame->color); band++)
+	 {
+	    src = dst = frame->pixels [band];
+	    for (y = orig_height; y; y--)
+	    {
+	       memmove (dst, src, orig_width * sizeof (word_t));
+	       dst += orig_width;
+	       src += width;
+	    }
+	    if (format == FORMAT_4_2_0 && band == Y)
+	    {
+	       orig_width  >>= 1;
+	       orig_height >>= 1;
+	       width       >>= 1;
+	    }
+	 }
+      }
+   }
+   if (dec_timer)
+      dec_timer [2] += prg_timer (&ptimer, STOP);
+
+   return frame;
+}
+
+image_t *
+decode_state (unsigned state, unsigned level, wfa_t *wfa)
+/*
+ *  Decode 'state' image of 'wfa' at given 'level'.
+ *
+ *  Return value.
+ *	pointer to decoded state image
+ *
+ *  Side effects:
+ *	'wfa' states > 'state' are removed.  
+ */
+{
+   word_t  *domains [2];
+   image_t *img = Calloc (1, sizeof (image_t));
+
+   /*
+    *  Generate a new state with a 1.0 transition to 'state'
+    */
+   remove_states (state + 1, wfa);
+   append_edge (state + 1, state, 1.0, 0, wfa);
+   wfa->states = state + 2;
+
+   img->color  = NO;
+   img->width  = width_of_level (level);
+   img->height = height_of_level (level);
+   img->format = FORMAT_4_4_4;
+   img->pixels [GRAY] = decode_range (state + 1, 0, level, domains, wfa);
+
+   /*
+    *  Copy decoded range to the frame buffer
+    */
+   {
+      word_t   *src, *dst;
+      unsigned	y;
+	    
+      src = domains [0];
+      dst = img->pixels [GRAY];
+      for (y = img->height; y; y--)
+      {
+	 memcpy (dst, src, width_of_level (level) * sizeof (word_t));
+	 src += width_of_level (level);
+	 dst += img->width;
+      }
+      Free (domains [0]);
+   }
+
+   return img;
+}
+
+word_t *
+decode_range (unsigned range_state, unsigned range_label, unsigned range_level,
+	      word_t **domain, wfa_t *wfa)
+/*
+ *  Compute 'wfa' image of range (identified by 'state' and 'label')
+ *  at 'range_level (works as function decode_image()).
+ *
+ *  Return value:
+ *	pointer to the pixels in SHORT format
+ *
+ *  Side effects:
+ *	if 'domain' != NULL then also the domain blocks
+ *	of the corresponding range blocks are generated
+ *      and returned in domain[]
+ *	'wfa->level_of_state []' is changed
+ */
+{
+   unsigned   root_state [3];		/* dummy (for alloc_state_images) */
+   image_t   *state_image;		/* regenerated state image */
+   word_t   **images;			/* pointer to array of pointers
+					   to state images */
+   u_word_t  *offsets;			/* pointer to array of state image
+					   offsets */
+   word_t    *range;
+
+   enlarge_image (range_level - (wfa->level_of_state [range_state] - 1),
+		  FORMAT_4_4_4, -1, wfa);
+   root_state [0] = range_state;
+   state_image    = alloc_image (width_of_level (range_level + 1),
+				 height_of_level (range_level + 1),
+				 NO, FORMAT_4_4_4);
+   alloc_state_images (&images, &offsets, state_image, NULL, range_state,
+		       range_level + 1, NO, wfa);
+   compute_state_images (range_level + 1, images, offsets, wfa);
+
+   range = Calloc (size_of_level (range_level), sizeof (word_t));
+
+   if ((range_level & 1) == 0)		/* square image */
+   {
+      memcpy (range,
+	      images [range_state + (range_level + 1) * wfa->states]
+	      + range_label * size_of_level (range_level),
+	      size_of_level (range_level) * sizeof (word_t));
+   }
+   else					/* rectangle */
+   {
+      word_t   *src, *dst;
+      unsigned  y;
+      
+      src = images [range_state + (range_level + 1) * wfa->states]
+	    + range_label * width_of_level (range_level);
+      dst = range;
+      for (y = height_of_level (range_level); y; y--)
+      {
+	 memcpy (dst, src, width_of_level (range_level) * sizeof (word_t));
+	 dst += width_of_level (range_level);
+	 src += width_of_level (range_level + 1);
+      }
+   }
+
+   if (domain != NULL)			/* copy domain images */
+   {
+      int      s;			/* domain state */
+      unsigned edge;			/* counter */
+		
+      if (ischild (s = wfa->tree [range_state][range_label]))
+	 *domain++ = duplicate_state_image (images [s + (range_level)
+						   * wfa->states],
+					    offsets [s + (range_level)
+						    * wfa->states],
+					    range_level);
+      for (edge = 0; isedge (s = wfa->into[range_state][range_label][edge]);
+	   edge++)
+	 *domain++ = duplicate_state_image (images [s + (range_level)
+						   * wfa->states],
+					    offsets [s + (range_level)
+						    * wfa->states],
+					    range_level);
+      *domain = NULL;
+   }
+   
+   free_state_images (range_level + 1, NO, images, offsets, NULL, range_state,
+		      NO, wfa);
+   free_image (state_image);
+   
+   return range;
+}
+
+void
+smooth_image (unsigned sf, const wfa_t *wfa, image_t *image)
+/*
+ *  Smooth 'image' along the partitioning boundaries of the 'wfa'
+ *  with factor 's'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	pixel values of the 'image' are modified with respect to 's'
+ */
+{
+   int	    is, inegs;			/* integer factors of s and 1 - s*/
+   unsigned state;			
+   unsigned img_width  = image->width;
+   unsigned img_height = image->height;
+   real_t   s 	       = 1.0 - sf / 200.0;
+
+   if (s < 0.5 || s >= 1)		/* value out of range */
+      return;
+
+   is 	 = s * 512 + .5;		/* integer representation of s */
+   inegs = (1 - s) * 512 + .5;		/* integer representation of 1 - s */
+   
+   for (state = wfa->basis_states;
+	state < (wfa->wfainfo->color
+		 ? wfa->tree [wfa->root_state][0]
+		 : wfa->states); state++)
+   {
+      word_t   *bptr   = image->pixels [Y]; /* pointer to right or
+					       lower line */
+      unsigned  level  = wfa->level_of_state[state]; /* level of state image */
+      unsigned  width  = width_of_level (level); /* size of state image */
+      unsigned  height = height_of_level (level); /* size of state image */
+      
+      if (wfa->y [state][1] >= img_height || wfa->x [state][1] >= img_width)
+	 continue;			/* outside visible area */
+	 
+      if (level % 2)			/* horizontal smoothing */
+      {
+	 unsigned  i;			/* line counter */
+	 word_t   *img1;		/* pointer to left or upper line */
+	 word_t   *img2;		/* pointer to right or lower line */
+
+	 img1 = bptr + (wfa->y [state][1] - 1) * img_width
+		+ wfa->x [state][1];
+	 img2 = bptr + wfa->y [state][1] * img_width + wfa->x [state][1];
+	 
+	 for (i = min (width, img_width - wfa->x [state][1]); i;
+	      i--, img1++, img2++)
+	 {
+	    int tmp = *img1;
+	    
+#ifdef HAVE_SIGNED_SHIFT
+	    *img1 = (((is * tmp) >> 10) << 1)
+		    + (((inegs * (int) *img2) >> 10) << 1);
+	    *img2 = (((is * (int) *img2) >> 10) << 1)
+		    + (((inegs * tmp) >> 10) << 1);
+#else /* not HAVE_SIGNED_SHIFT */
+	    *img1 = (((is * tmp) / 1024) * 2)
+		    + (((inegs * (int) *img2) / 1024) * 2);
+	    *img2 = (((is * (int) *img2) / 1024) * 2)
+		    + (((inegs * tmp) / 1024) *2);
+#endif /* not HAVE_SIGNED_SHIFT */
+	 }
+      }
+      else				/* vertical smoothing */
+      {
+	 unsigned  i;			/* line counter */
+	 word_t   *img1;		/* pointer to left or upper line */
+	 word_t   *img2;		/* pointer to right or lower line */
+
+	 img1 = bptr + wfa->y [state][1] * img_width + wfa->x [state][1] - 1;
+	 img2 = bptr + wfa->y [state][1] * img_width + wfa->x [state][1];
+	 
+	 for (i = min (height, img_height - wfa->y [state][1]); i;
+	      i--, img1 += img_width, img2 += img_width)
+	 {
+	    int tmp = *img1;
+	    
+#ifdef HAVE_SIGNED_SHIFT
+	    *img1 = (((is * tmp) >> 10) << 1)
+		    + (((inegs * (int) *img2) >> 10) << 1);
+	    *img2 = (((is * (int) *img2) >> 10) << 1)
+		    + (((inegs * tmp) >> 10) << 1);
+#else /* not HAVE_SIGNED_SHIFT */
+	    *img1 = (((is * tmp) / 1024) * 2)
+		    + (((inegs * (int) *img2) / 1024) * 2);
+	    *img2 = (((is * (int) *img2) / 1024) * 2)
+		    + (((inegs * tmp) / 1024) *2);
+#endif /* not HAVE_SIGNED_SHIFT */
+	 }
+      }
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+enlarge_image (int enlarge_factor, format_e format, unsigned y_root,
+	       wfa_t *wfa)
+/*
+ *  Enlarge or reduce size of state images by factor 2^'enlarge_factor'.
+ *  Use 4:2:0 subsampling if specified by 'format', else use 4:4:4 format.
+ *  'wfa' root state of the first chroma band is given by 'y_root' + 1.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	coordinates of ranges and motion blocks in the WFA structure 'wfa'
+ *	are modified.
+ */
+{
+   
+   if (enlarge_factor != 0 || format == FORMAT_4_2_0)
+   {
+      unsigned state;
+
+      if (enlarge_factor == 0)
+      {
+	 state 		= y_root + 1;
+	 enlarge_factor = -1;
+      }
+      else
+	 state = wfa->basis_states;
+      
+      for (; state < wfa->states; state++)
+      {
+	 unsigned label, n;
+	 
+	 wfa->level_of_state [state]
+	    = max (wfa->level_of_state [state] + enlarge_factor * 2, 0);
+
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (enlarge_factor > 0)
+	    {
+	       wfa->x [state][label] <<= enlarge_factor;
+	       wfa->y [state][label] <<= enlarge_factor;
+	       for (n = enlarge_factor; n; n--)
+	       {
+		  wfa->mv_tree [state][label].fx *= 2;
+		  wfa->mv_tree [state][label].fy *= 2;
+		  wfa->mv_tree [state][label].bx *= 2;
+		  wfa->mv_tree [state][label].by *= 2;
+	       }
+	    }
+	    else				/* enlarge_factor < 0 */
+	    {
+	       wfa->x [state][label] >>= - enlarge_factor;
+	       wfa->y [state][label] >>= - enlarge_factor;
+	       for (n = - enlarge_factor; n; n--)
+	       {
+		  wfa->mv_tree [state][label].fx /= 2;
+		  wfa->mv_tree [state][label].fy /= 2;
+		  wfa->mv_tree [state][label].bx /= 2;
+		  wfa->mv_tree [state][label].by /= 2;
+	       }
+	    }
+	 if (format == FORMAT_4_2_0 && state == y_root)
+	    enlarge_factor--;
+      }
+   }
+}
+
+static void
+compute_actual_size (unsigned luminance_root,
+		     unsigned *width, unsigned *height, const wfa_t *wfa)
+/*
+ *  Compute actual size of the frame represented by the given 'wfa'.
+ *  (The reconstructed frame may get larger than the original due
+ *   to the bintree partitioning.)
+ *  If 'luminance_root' < MAXSTATES then the size of chroma ranges (4:2:0).
+ *
+ *  Return values:
+ *	actual 'width' and 'height' of the decoded frame.
+ */
+{
+   unsigned x = 0, y = 0;		/* maximum coordinates */
+   unsigned state;			/* counter */
+   
+   for (state = wfa->basis_states; state < wfa->states; state++)
+      if (isedge (wfa->into [state][0][0]) || isedge (wfa->into [state][1][0]))
+      {
+	 unsigned mult = state > luminance_root ? 2 : 1;
+	 
+	 x = max ((wfa->x [state][0]
+		   + width_of_level (wfa->level_of_state [state])) * mult, x);
+	 y = max ((wfa->y [state][0]
+		   + height_of_level (wfa->level_of_state [state])) * mult, y);
+      }
+
+   if (x & 1)				/* ensure that image size is even */
+      x++;
+   if (y & 1)
+      y++;
+   *width  = x;
+   *height = y;
+}
+
+static void
+alloc_state_images (word_t ***images, u_word_t **offsets, const image_t *frame,
+		    const unsigned *root_state, unsigned range_state,
+		    unsigned max_level, format_e format, const wfa_t *wfa)
+/*
+ *  Generate list of 'wfa' state images which have to be computed for
+ *  each level to obtain the decoded 'frame'. 'root_state[]' denotes the
+ *  state images of the three color bands.
+ *  'max_level' fives the max. level of a linear combination.
+ *  Memory is allocated for every required state image.
+ *  Use 4:2:0 subsampling or 4:4:4 'format' for color images.
+ *  If 'range_state' > 0 then rather compute image of 'range_state' than 
+ *  image of 'wfa->root_state'.
+ *
+ *  Return values:
+ *	'*images'	Pointer to array of state image pointers
+ *	'*offsets'	Pointer to array of state image offsets.
+ *
+ *  Side effects:
+ *	The arrays given above are filled with useful values.
+ */
+{
+   word_t   **simg;			/* ptr to list of state image ptr's */
+   u_word_t  *offs;			/* ptr to list of offsets */
+   unsigned   level;			/* counter */
+   
+   simg	= Calloc (wfa->states * (max_level + 1), sizeof (word_t *));
+   offs	= Calloc (wfa->states * (max_level + 1), sizeof (u_word_t));
+
+   /*
+    *  Initialize buffers for those state images which are at 'max_level'.
+    */
+   if (range_state > 0)			/* a range is given */
+   {
+      simg [range_state + max_level * wfa->states] = frame->pixels [GRAY];
+      offs [range_state + max_level * wfa->states] = frame->width;
+   }
+   else
+   {
+      unsigned state;
+
+      for (state = wfa->basis_states; state <= root_state [Y]; state++)
+	 if (wfa->level_of_state [state] == max_level)
+	 {
+	    simg [state + max_level * wfa->states]
+	       = (frame->pixels [Y] + wfa->y [state][0] * frame->width
+		  + wfa->x [state][0]);
+	    offs [state + max_level * wfa->states] = frame->width;
+	 }
+      if (frame->color)
+      {
+	 unsigned width = format == FORMAT_4_2_0 ?
+			  (frame->width >> 1) : frame->width;
+	 for (; state < wfa->states; state++)
+	    if (wfa->level_of_state [state] == max_level)
+	    {
+	       simg [state + max_level * wfa->states]
+		  = (frame->pixels [state > root_state [Cb] ? Cr : Cb]
+		     + wfa->y [state][0] * width + wfa->x [state][0]);
+	       offs [state + max_level * wfa->states] = width;
+	    }
+      }
+   }
+   
+   /*
+    *  Generate list of state images which must be computed at each level
+    */
+   for (level = max_level; level > 0; level--)
+   {
+      int      child, domain;
+      unsigned state, label, edge;
+      
+      /*
+       *  Range approximation with child. 
+       */
+      for (state = 1; state < (range_state > 0 ?
+			       range_state + 1 : wfa->states); state++)
+	 if (simg [state + level * wfa->states])
+	    for (label = 0; label < MAXLABELS; label++)
+	       if (ischild (child = wfa->tree[state][label]))
+	       {
+		  if (isedge (wfa->into[state][label][0]))
+		  {
+		     /*
+		      *  Allocate new image block.
+		      */
+		     simg [child + (level - 1) * wfa->states]
+			= Calloc (size_of_level (level - 1), sizeof (word_t));
+		     offs [child + (level - 1) * wfa->states]
+			= width_of_level (level - 1);
+		  }
+		  else
+		  {
+		     /*
+		      *  Use image block and offset of parent.
+		      */
+		     if (level & 1)	/* split vertically */
+		     {
+			simg [child + (level - 1) * wfa->states]
+			   = (simg [state + level * wfa->states]
+			      + label * (height_of_level (level - 1)
+					 * offs [state
+						+ level * wfa->states]));
+		     }
+		     else		/* split horizontally */
+		     {
+			simg [child + (level - 1) * wfa->states]
+			   = (simg [state + level * wfa->states]
+			      + label * width_of_level (level - 1));
+		     }
+		     offs [child + (level - 1) * wfa->states]
+			= offs [state + level * wfa->states];
+		  }
+	       }
+      /*
+       *  Range approximation with linear combination 
+       */
+      for (state = 1; state < (range_state > 0 ?
+			       range_state + 1 : wfa->states); state++)
+	 if (simg [state + level * wfa->states])
+	    for (label = 0; label < MAXLABELS; label++)
+	       for (edge = 0; isedge (domain = wfa->into[state][label][edge]);
+		    edge++)
+	       {
+		  if (domain > 0	/* don't allocate memory for state 0 */
+		      && !simg [domain + (level - 1) * wfa->states])
+		  {
+		     simg [domain + (level - 1) * wfa->states]
+			= Calloc (size_of_level (level - 1), sizeof (word_t));
+		     offs [domain + (level - 1) * wfa->states]
+			= width_of_level (level - 1);
+		  }
+	       }
+      
+   }
+
+   *images  = simg;
+   *offsets = offs;
+}
+
+static void
+free_state_images (unsigned max_level, bool_t color, word_t **state_image,
+		   u_word_t *offset, const unsigned *root_state,
+		   unsigned range_state, format_e format, const wfa_t *wfa)
+/*
+ *  Free memory of state images.
+ *  For more details refer to the inverse function 'alloc_state_images()'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	arrays 'state_image' and 'offset' are discarded.
+ */
+{
+   word_t   marker;			/* ptr is required as a marker */
+   unsigned level;
+
+   if (range_state > 0)
+   {
+      state_image [range_state + max_level * wfa->states] = &marker;
+   }
+   else
+   {
+      unsigned state;
+      
+      /*
+       *  Initialize state image array with states at 'max_level'
+       */
+      for (state = wfa->basis_states; state <= root_state [Y]; state++)
+	 if (wfa->level_of_state [state] == max_level)
+	    state_image [state + max_level * wfa->states] = &marker;
+
+      if (color)
+      {
+	 if (format == FORMAT_4_2_0)
+	    level = max_level - 2;
+	 else
+	    level = max_level;
+      
+	 for (; state < wfa->states; state++)
+	    if (wfa->level_of_state [state] == level)
+	       state_image [state + level * wfa->states] = &marker;
+      }
+   }
+   
+   for (level = max_level; level > 0; level--)
+   {
+      int      domain, child;
+      unsigned state, label, edge;
+      /*
+       *  Range approximation with child. 
+       */
+      for (state = 1; state < (range_state > 0 ?
+			       range_state + 1 : wfa->states); state++)
+	 if (state_image [state + level * wfa->states])
+	    for (label = 0; label < MAXLABELS; label++)
+	       if (ischild (child = wfa->tree[state][label]))
+	       {
+		  if (isedge (wfa->into[state][label][0])
+		      && (state_image [child + (level - 1) * wfa->states]
+			  != &marker))
+		     Free (state_image [child + (level - 1) * wfa->states]);
+		  state_image [child + (level - 1) * wfa->states] = &marker;
+	       }
+      /*
+       *  Range approximation with linear combination 
+       */
+      for (state = 1; state < (range_state > 0 ?
+			       range_state + 1 : wfa->states);
+	   state++)
+	 if (state_image [state + level * wfa->states])
+	    for (label = 0; label < MAXLABELS; label++)
+	       for (edge = 0; isedge (domain = wfa->into[state][label][edge]);
+		    edge++)
+		  if (domain > 0	
+		      && (state_image [domain + (level - 1) * wfa->states]
+			  != NULL)
+		      && (state_image [domain + (level - 1) * wfa->states]
+			  != &marker))
+		  {
+		     Free (state_image [domain + (level - 1) * wfa->states]);
+		     state_image [domain + (level - 1) * wfa->states]
+			= &marker;
+		  }
+   }
+   Free (state_image);
+   Free (offset);
+}
+
+static void
+compute_state_images (unsigned max_level, word_t **simg,
+		      const u_word_t *offset, const wfa_t *wfa)
+/*
+ *  Compute all state images of the 'wfa' at level {1, ... , 'max_level'}
+ *  which are marked in the array 'simg' (offsets of state images
+ *  are given by 'offset').
+ *
+ *  Warning: Several optimizations are used in this function making 
+ *  it difficult to understand.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	state images (given by pointers in the array 'state_image')
+ *	are computed.
+ */
+{
+   unsigned level, state;
+     
+   /*
+    *  Copy one-pixel images in case state_image pointer != &final distr.
+    */
+
+   for (state = 1; state < wfa->states; state++)
+      if (simg [state] != NULL)		/* compute image at level 0 */
+	 *simg [state] = (int) (wfa->final_distribution[state] * 8 + .5) * 2;
+
+   /*
+    *  Compute images of states
+    *  Integer arithmetics are used rather than floating point operations.
+    *  'weight' gives the weight in integer notation
+    *  'src', 'dst', and 'idst' are pointers to the source and
+    *  destination pixels (short or integer format), respectively.
+    *  Short format : one operation per register (16 bit mode). 
+    *  Integer format : two operations per register (32 bit mode). 
+    *  'src_offset', 'dst_offset', and 'dst_offset' give the number of
+    *  pixels which have to be omitted when jumping to the next image row.
+    */
+   for (level = 1; level <= max_level; level++) 
+   {
+      unsigned label;
+      unsigned width  = width_of_level (level - 1);
+      unsigned height = height_of_level (level - 1);
+      
+      for (state = 1; state < wfa->states; state++)
+	 if (simg [state + level * wfa->states] != NULL)
+	    for (label = 0; label < MAXLABELS; label++)
+	       if (isedge (wfa->into [state][label][0]))
+	       {
+		  unsigned  edge;
+		  int       domain;
+		  word_t   *range;	/* address of current range */
+		  bool_t    prediction_used; /* ND prediction found ? */
+
+		  /*
+		   *  Compute address of range image
+		   */
+		  if (level & 1)	/* split vertically */
+		  {
+		     range = simg [state + level * wfa->states]
+			     + label * (height_of_level (level - 1)
+					* offset [state
+						 + level * wfa->states]);
+		  }
+		  else			/* split horizontally */
+		  {
+		     range = simg [state + level * wfa->states]
+			     + label * width_of_level (level - 1);
+		  }
+
+		  /*
+		   *  Generate the state images by adding the corresponding 
+		   *  weighted state images:
+		   *  subimage [label] =
+		   *       weight_1 * image_1 + ... + weight_n * image_n
+		   */
+		  if (!ischild (domain = wfa->tree[state][label]))
+		     prediction_used = NO;
+		  else
+		  {
+		     unsigned  y;
+		     word_t   *src;
+		     word_t   *dst;
+		     unsigned  src_offset;
+		     unsigned  dst_offset;
+
+		     prediction_used = YES;
+		     /*
+		      *  Copy child image
+		      */
+		     src        = simg [domain + (level - 1) * wfa->states];
+		     src_offset = offset [domain + (level - 1) * wfa->states] ;
+		     dst        = range;
+		     dst_offset	= offset [state + level * wfa->states];
+		     for (y = height; y; y--)
+		     {
+			memcpy (dst, src, width * sizeof (word_t));
+			src += src_offset;
+			dst += dst_offset;
+		     }
+		  }
+
+		  if (!prediction_used
+		      && isedge (domain = wfa->into[state][label][0]))
+		  {
+		     /*
+		      *  If prediction is not used then the range is
+		      *  filled with the first domain. No addition is needed.
+		      */
+		     edge = 0;
+		     if (domain != 0)
+		     {
+			int	  weight;
+			word_t 	 *src;
+			unsigned  src_offset;
+
+			src        = simg [domain + ((level - 1)
+						     * wfa->states)];
+			src_offset = offset [domain + ((level - 1)
+						       * wfa->states)] - width;
+			weight     = wfa->int_weight [state][label][edge];
+			
+			if (width == 1)	/* can't add two-pixels in a row */
+			{
+			   word_t   *dst;
+			   unsigned  dst_offset;
+			   
+			   dst        = range;
+			   dst_offset = offset [state + level * wfa->states]
+					- width;
+#ifdef HAVE_SIGNED_SHIFT
+			   *dst++ = ((weight * (int) *src++) >> 10) << 1;
+#else 					/* not HAVE_SIGNED_SHIFT */
+			   *dst++ = ((weight * (int) *src++) / 1024) * 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+			   if (height == 2) 
+			   {
+			      src += src_offset;
+			      dst += dst_offset;
+#ifdef HAVE_SIGNED_SHIFT
+			      *dst++ = ((weight * (int) *src++) >> 10) << 1;
+#else /* not HAVE_SIGNED_SHIFT */
+			      *dst++ = ((weight * (int) *src++) / 1024) * 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+			   }
+			}
+			else
+			{
+			   unsigned  y;
+			   int 	    *idst;
+			   unsigned  idst_offset;
+			   
+			   idst        = (int *) range;
+			   idst_offset = (offset [state + level * wfa->states]
+					  - width) / 2;
+			   for (y = height; y; y--)
+			   {
+			      int *comp_dst = idst + (width >> 1);
+			      
+			      for (; idst != comp_dst; )
+ 			      {
+				 int tmp; /* temp. value of adjacent pixels */
+#ifdef HAVE_SIGNED_SHIFT
+#	ifndef WORDS_BIGENDIAN
+                                 tmp = (((weight * (int) src [1]) >> 10) << 17)
+				       | (((weight * (int) src [0]) >> 9)
+					  & 0xfffe);
+#	else /* not WORDS_BIGENDIAN */
+                                 tmp = (((weight * (int) src [0]) >> 10) << 17)
+				       | (((weight * (int) src [1]) >> 9)
+					  & 0xfffe);
+#	endif /* not WORDS_BIGENDIAN */
+#else /* not HAVE_SIGNED_SHIFT */
+#	ifndef WORDS_BIGENDIAN
+                                 tmp = (((weight * (int) src [1]) / 1024)
+					* 131072)
+				       | (((weight * (int) src [0])/ 512)
+					  & 0xfffe);
+#	else /* not WORDS_BIGENDIAN */
+                                 tmp = (((weight * (int) src [0]) / 1024)
+					* 131072)
+				       | (((weight * (int) src [1]) / 512)
+					  & 0xfffe);
+#	endif /* not WORDS_BIGENDIAN */
+#endif /* not HAVE_SIGNED_SHIFT */
+				 src    +=  2;
+				 *idst++ = tmp & 0xfffefffe;
+			      }
+			      src  += src_offset;
+			      idst += idst_offset;
+			   }
+			}
+		     }
+		     else
+		     {
+			int weight = (int) (wfa->weight[state][label][edge]
+					    * wfa->final_distribution[0]
+					    * 8 + .5) * 2;
+			/*
+			 *  Range needs domain 0
+			 *  (the constant function f(x, y) = 1),
+			 *  hence a faster algorithm is used.
+			 */
+			if (width == 1)	/* can't add two-pixels in a row */
+			{
+			   word_t   *dst;
+			   unsigned  dst_offset;
+			   
+			   dst        = range;
+			   dst_offset = offset [state + level * wfa->states]
+					- width;
+			   
+			   *dst++ = weight;
+			   if (height == 2)
+			   {
+			      dst += dst_offset;
+			      *dst++ = weight;
+			   }
+			}
+			else
+			{
+			   unsigned  x, y;
+			   int 	    *idst;
+			   unsigned  idst_offset;
+			   
+			   weight      = (weight * 65536) | (weight & 0xffff);
+			   idst	       = (int *) range;
+			   idst_offset = offset [state + level * wfa->states]
+					 / 2;
+			   for (x = width >> 1; x; x--)
+			      *idst++ = weight & 0xfffefffe;
+			   idst += (offset [state + level * wfa->states]
+				    - width) / 2;
+
+			   for (y = height - 1; y; y--)
+			   {
+			      memcpy (idst, idst - idst_offset,
+				      width * sizeof (word_t));
+			      idst += idst_offset;
+			   }
+			}
+		     }
+		     edge = 1;
+		  }
+		  else
+		     edge = 0;
+		  
+		  /*
+		   *  Add remaining weighted domain images to current range
+		   */
+		  for (; isedge (domain = wfa->into[state][label][edge]);
+		       edge++)
+		  {
+		     if (domain != 0)
+		     {
+			word_t 	 *src;
+			unsigned  src_offset;
+			int	  weight;
+
+			src        = simg [domain + (level - 1) * wfa->states];
+			src_offset = offset [domain + ((level - 1)
+						       * wfa->states)] - width;
+			weight     = wfa->int_weight [state][label][edge];
+			
+			if (width == 1)	/* can't add two-pixels in a row */
+			{
+			   word_t   *dst;
+			   unsigned  dst_offset;
+			   
+			   dst        = range;
+			   dst_offset = offset [state + level * wfa->states]
+					- width;
+
+#ifdef HAVE_SIGNED_SHIFT
+			   *dst++ += ((weight * (int) *src++) >> 10) << 1;
+#else /* not HAVE_SIGNED_SHIFT */
+			   *dst++ += ((weight * (int) *src++) / 1024) * 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+			   if (height == 2) 
+			   {
+			      src += src_offset;
+			      dst += dst_offset;
+#ifdef HAVE_SIGNED_SHIFT
+			      *dst++ += ((weight * (int) *src++) >> 10) << 1;
+#else /* not HAVE_SIGNED_SHIFT */
+			      *dst++ += ((weight * (int) *src++) / 1024) * 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+			   }
+			}
+			else
+			{
+			   int 	    *idst;
+			   unsigned  idst_offset;
+			   unsigned  y;
+			   
+			   idst        = (int *) range;
+			   idst_offset = (offset [state + level * wfa->states]
+					  - width) / 2;
+			   
+			   for (y = height; y; y--)
+			   {
+			      int *comp_dst = idst + (width >> 1);
+			      
+			      for (; idst != comp_dst;)
+ 			      {
+				 int tmp; /* temp. value of adjacent pixels */
+#ifdef HAVE_SIGNED_SHIFT
+#	ifndef WORDS_BIGENDIAN
+                                 tmp = (((weight * (int) src [1]) >> 10) << 17)
+				       | (((weight * (int) src [0]) >> 9)
+					  & 0xfffe);
+#	else /* not WORDS_BIGENDIAN */
+                                 tmp = (((weight * (int)src [0]) >> 10) << 17)
+				       | (((weight * (int)src [1]) >> 9)
+					  & 0xfffe);
+#	endif /* not WORDS_BIGENDIAN */
+#else /* not HAVE_SIGNED_SHIFT */
+#	ifndef WORDS_BIGENDIAN
+                                 tmp = (((weight * (int) src [1]) / 1024)
+					* 131072)
+				       | (((weight * (int) src [0])/ 512)
+					  & 0xfffe);
+#	else /* not WORDS_BIGENDIAN */
+                                 tmp = (((weight * (int) src [0]) / 1024)
+					* 131072)
+				       | (((weight * (int) src [1])/ 512)
+					  & 0xfffe);
+#	endif /* not WORDS_BIGENDIAN */
+#endif /* not HAVE_SIGNED_SHIFT */
+				 src +=  2;
+				 *idst = (*idst + tmp) & 0xfffefffe;
+				 idst++;
+			      }
+			      src  += src_offset;
+			      idst += idst_offset;
+			   }
+			}
+		     }
+		     else
+		     {
+			int weight = (int) (wfa->weight[state][label][edge]
+					    * wfa->final_distribution[0]
+					    * 8 + .5) * 2;
+			/*
+			 *  Range needs domain 0
+			 *  (the constant function f(x, y) = 1),
+			 *  hence a faster algorithm is used.
+			 */
+			if (width == 1)	/* can't add two-pixels in a row */
+			{
+			   word_t   *dst;
+			   unsigned  dst_offset;
+			   
+			   dst        = range;
+			   dst_offset = offset [state + level * wfa->states]
+					- width;
+			   
+			   *dst++ += weight;
+			   if (height == 2)
+			   {
+			      dst    += dst_offset;
+			      *dst++ += weight;
+			   }
+			}
+			else
+			{
+			   int 	    *idst;
+			   unsigned  idst_offset;
+			   unsigned  y;
+			   
+			   weight      = (weight * 65536) | (weight & 0xffff);
+			   idst	       = (int *) range;
+			   idst_offset = (offset [state + level * wfa->states]
+					  - width) /2;
+			   
+			   for (y = height; y; y--)
+			   {
+			      int *comp_dst = idst + (width >> 1);
+			      
+			      for (; idst != comp_dst; )
+			      {
+				 *idst = (*idst + weight) & 0xfffefffe;
+                                 idst++;
+			      }
+			      idst += idst_offset;
+			   }
+			}
+		     }
+		  }
+	       } 
+   }
+}
+
+static word_t *
+duplicate_state_image (const word_t *domain, unsigned offset, unsigned level)
+/*
+ *  Allocate new memory block 'pixels' and copy pixel values of 'domain' 
+ *  (size and pixel offset are given by 'level' and 'offset')
+ *  to the lock 'pixels'.
+ *
+ *  Return value:
+ *	pointer to the new domain block
+ */
+{
+   word_t *dst, *pixels;
+   int	   y, n;
+
+   dst = pixels = Calloc (size_of_level (level), sizeof (word_t));
+
+   if (domain)
+      for (y = height_of_level (level); y; y--)
+      {
+	 memcpy (dst, domain, width_of_level (level) * sizeof (word_t));
+	 dst    += width_of_level (level);
+	 domain += offset;
+      }
+   else					/* state 0 */
+      for (n = size_of_level (level); n; n--)
+	 *dst++ = (int) (128 * 8 + .5) * 2;
+
+   return pixels;
+}
diff --git a/converter/other/fiasco/codec/decoder.h b/converter/other/fiasco/codec/decoder.h
new file mode 100644
index 00000000..8cd211e0
--- /dev/null
+++ b/converter/other/fiasco/codec/decoder.h
@@ -0,0 +1,70 @@
+/*
+ *  decode.h
+ *		
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/10/22 10:44:48 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#ifndef _DECODE_H
+#define _DECODE_H
+
+#include "types.h"
+#include "image.h"
+#include "wfa.h"
+
+typedef struct video
+{
+   unsigned  future_display;		/* number of a future frame */
+   unsigned  display;			/* current display number */
+   image_t  *frame;			/* current frame */
+   image_t  *sframe;			/* current smoothed frame */
+   image_t  *future;			/* future reference */
+   image_t  *sfuture;			/* future (smmothed) reference */
+   image_t  *past ;			/* past reference */
+   wfa_t    *wfa;			/* current wfa */
+   wfa_t    *wfa_future;		/* future wfa */
+   wfa_t    *wfa_past;			/* past wfa */
+} video_t;
+
+typedef struct dectimer
+{
+   unsigned int	input [3];
+   unsigned int	preprocessing [3];
+   unsigned int	decoder [3];
+   unsigned int	cleanup [3];
+   unsigned int	motion [3];
+   unsigned int	smooth [3];
+   unsigned int	display [3];
+   unsigned int	frames [3];
+} dectimer_t;
+
+image_t *
+get_next_frame (bool_t store_wfa, int enlarge_factor,
+		int smoothing, const char *reference_frame,
+		format_e format, video_t *video, dectimer_t *timer,
+		wfa_t *orig_wfa, bitfile_t *input);
+image_t *
+decode_image (unsigned orig_width, unsigned orig_height, format_e format,
+	      unsigned *dec_timer, const wfa_t *wfa);
+word_t *
+decode_range (unsigned range_state, unsigned range_label, unsigned range_level,
+	      word_t **domain, wfa_t *wfa);
+image_t *
+decode_state (unsigned state, unsigned level, wfa_t *wfa);
+void
+smooth_image (unsigned sf, const wfa_t *wfa, image_t *image);
+video_t *
+alloc_video (bool_t store_wfa);
+void
+free_video (video_t *video);
+
+#endif /* not _DECODE_H */
diff --git a/converter/other/fiasco/codec/dfiasco.c b/converter/other/fiasco/codec/dfiasco.c
new file mode 100644
index 00000000..1cdfc672
--- /dev/null
+++ b/converter/other/fiasco/codec/dfiasco.c
@@ -0,0 +1,398 @@
+/*
+ *  dfiasco.c:		Decoder public interface
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+ 
+/*
+ *  $Date: 2000/10/28 17:39:30 $
+ *  $Author: hafner $
+ *  $Revision: 5.7 $
+ *  $State: Exp $
+ */
+
+#include <string.h>
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "dfiasco.h"
+#include "wfa.h"
+#include "read.h"
+#include "misc.h"
+#include "bit-io.h"
+#include "decoder.h"
+#include "options.h"
+#include "wfalib.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static dfiasco_t *
+cast_dfiasco (fiasco_decoder_t *dfiasco);
+static void
+free_dfiasco (dfiasco_t *dfiasco);
+static dfiasco_t *
+alloc_dfiasco (wfa_t *wfa, video_t *video, bitfile_t *input,
+	       int enlarge_factor, int smoothing, format_e image_format);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+fiasco_decoder_t *
+fiasco_decoder_new (const char *filename, const fiasco_d_options_t *options)
+{
+   try
+   {
+      bitfile_t        	 *input;	/* pointer to WFA FIASCO stream */
+      wfa_t            	 *wfa;		/* wfa structure */
+      video_t          	 *video;	/* information about decoder state */
+      const d_options_t  *dop;		/* decoder additional options */
+      dfiasco_t	       	 *dfiasco;	/* decoder internal state */
+      fiasco_decoder_t 	 *decoder;	/* public interface to decoder */
+      fiasco_d_options_t *default_options = NULL;
+
+      if (options)
+      {
+	 dop = cast_d_options ((fiasco_d_options_t *) options);
+	 if (!dop)
+	    return NULL;
+      }
+      else
+      {
+	 default_options = fiasco_d_options_new ();
+	 dop 		 = cast_d_options (default_options);
+      }
+      
+      wfa   = alloc_wfa (NO);
+      video = alloc_video (NO);
+      input = open_wfa (filename, wfa->wfainfo);
+      read_basis (wfa->wfainfo->basis_name, wfa);
+
+      decoder 	       	   = Calloc (1, sizeof (fiasco_decoder_t));
+      decoder->delete  	   = fiasco_decoder_delete;
+      decoder->write_frame = fiasco_decoder_write_frame;
+      decoder->get_frame   = fiasco_decoder_get_frame;
+      decoder->get_length  = fiasco_decoder_get_length;
+      decoder->get_rate    = fiasco_decoder_get_rate;
+      decoder->get_width   = fiasco_decoder_get_width;
+      decoder->get_height  = fiasco_decoder_get_height;
+      decoder->get_title   = fiasco_decoder_get_title;
+      decoder->get_comment = fiasco_decoder_get_comment;
+      decoder->is_color    = fiasco_decoder_is_color;
+
+      decoder->private = dfiasco
+		       = alloc_dfiasco (wfa, video, input,
+					dop->magnification,
+					dop->smoothing,
+					dop->image_format);
+   
+      if (default_options)
+	 fiasco_d_options_delete (default_options);
+      if (dfiasco->enlarge_factor >= 0)
+      {
+	 int 	       n;
+	 unsigned long pixels = wfa->wfainfo->width * wfa->wfainfo->height;
+
+	 for (n = 1; n <= (int) dfiasco->enlarge_factor; n++)
+	 {
+	    if (pixels << (n << 1) > 2048 * 2048)
+	    {
+	       set_error (_("Magnifaction factor `%d' is too large. "
+			    "Maximium value is %d."),
+			  dfiasco->enlarge_factor, max (0, n - 1));
+	       fiasco_decoder_delete (decoder);
+	       return NULL;
+	    }
+	 }
+      }
+      else
+      {
+	 int n;
+
+	 for (n = 0; n <= (int) - dfiasco->enlarge_factor; n++)
+	 {
+	    if (wfa->wfainfo->width >> n < 32
+		|| wfa->wfainfo->height >> n < 32)
+	    {
+	       set_error (_("Magnifaction factor `%d' is too small. "
+			    "Minimum value is %d."),
+			  dfiasco->enlarge_factor, - max (0, n - 1));
+	       fiasco_decoder_delete (decoder);
+	       return NULL;
+	    }
+	 }
+      }
+      return (fiasco_decoder_t *) decoder;
+   }
+   catch
+   {
+      return NULL;
+   }
+}
+
+int
+fiasco_decoder_write_frame (fiasco_decoder_t *decoder,
+			    const char *filename)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+   
+   if (!dfiasco)
+      return 0;
+   else
+   {
+      try
+      {
+	 image_t *frame = get_next_frame (NO, dfiasco->enlarge_factor,
+					  dfiasco->smoothing, NULL,
+					  FORMAT_4_4_4, dfiasco->video, NULL,
+					  dfiasco->wfa, dfiasco->input);
+	 write_image (filename, frame);
+      }
+      catch
+      {
+	 return 0;
+      }
+      return 1;
+   }
+}
+
+fiasco_image_t *
+fiasco_decoder_get_frame (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+   
+   if (!dfiasco)
+      return NULL;
+   else
+   {
+      try
+      {
+	 fiasco_image_t *image = Calloc (1, sizeof (fiasco_image_t));
+	 image_t 	*frame = get_next_frame (NO, dfiasco->enlarge_factor,
+						 dfiasco->smoothing, NULL,
+						 dfiasco->image_format,
+						 dfiasco->video, NULL,
+						 dfiasco->wfa, dfiasco->input);
+
+	 frame->reference_count++;	/* for motion compensation */
+	 image->private    = frame;
+	 image->delete     = fiasco_image_delete;
+	 image->get_width  = fiasco_image_get_width;
+	 image->get_height = fiasco_image_get_height;
+	 image->is_color   = fiasco_image_is_color;
+	 
+	 return image;
+      }
+      catch
+      {
+	 return NULL;
+      }
+   }
+}
+
+unsigned
+fiasco_decoder_get_length (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+   
+   if (!dfiasco)
+      return 0;
+   else
+      return dfiasco->wfa->wfainfo->frames;
+}
+
+unsigned
+fiasco_decoder_get_rate (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+   
+   if (!dfiasco)
+      return 0;
+   else
+      return dfiasco->wfa->wfainfo->fps;
+}
+
+unsigned
+fiasco_decoder_get_width (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+
+   if (!dfiasco)
+      return 0;
+   else
+   {
+      unsigned width;
+      
+      if (dfiasco->enlarge_factor >= 0)
+	 width = dfiasco->wfa->wfainfo->width << dfiasco->enlarge_factor;
+      else
+	 width = dfiasco->wfa->wfainfo->width >> - dfiasco->enlarge_factor;
+      
+      return width & 1 ? width + 1 : width;
+   }
+}
+
+unsigned
+fiasco_decoder_get_height (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+
+   if (!dfiasco)
+      return 0;
+   else
+   {
+      unsigned height;
+      
+      if (dfiasco->enlarge_factor >= 0)
+	 height = dfiasco->wfa->wfainfo->height << dfiasco->enlarge_factor;
+      else
+	 height = dfiasco->wfa->wfainfo->height >> - dfiasco->enlarge_factor;
+
+      return height & 1 ? height + 1 : height;
+   }
+}
+
+const char *
+fiasco_decoder_get_title (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+
+   if (!dfiasco)
+      return NULL;
+   else
+      return dfiasco->wfa->wfainfo->title;
+}
+
+const char *
+fiasco_decoder_get_comment (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+
+   if (!dfiasco)
+      return NULL;
+   else
+      return dfiasco->wfa->wfainfo->comment;
+}
+
+int
+fiasco_decoder_is_color (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+
+   if (!dfiasco)
+      return 0;
+   else
+      return dfiasco->wfa->wfainfo->color;
+}
+
+int
+fiasco_decoder_delete (fiasco_decoder_t *decoder)
+{
+   dfiasco_t *dfiasco = cast_dfiasco (decoder);
+   
+   if (!dfiasco)
+      return 1;
+   
+   try
+   {
+      free_wfa (dfiasco->wfa);
+      free_video (dfiasco->video);
+      close_bitfile (dfiasco->input);
+      strcpy (dfiasco->id, " ");
+      free_dfiasco(dfiasco);
+      Free (decoder);
+   }
+   catch
+   {
+      return 0;
+   }
+
+   return 1;
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static dfiasco_t *
+alloc_dfiasco (wfa_t *wfa, video_t *video, bitfile_t *input,
+	       int enlarge_factor, int smoothing, format_e image_format)
+/*
+ *  FIASCO decoder constructor:
+ *  Initialize decoder structure.
+ *
+ *  Return value:
+ *	pointer to the new decoder structure
+ */
+{
+   dfiasco_t *dfiasco = Calloc (1, sizeof (dfiasco_t));
+
+   strcpy (dfiasco->id, "DFIASCO");
+   
+   dfiasco->wfa 	   = wfa;
+   dfiasco->video 	   = video;
+   dfiasco->input 	   = input;
+   dfiasco->enlarge_factor = enlarge_factor;
+   dfiasco->smoothing  	   = smoothing;
+   dfiasco->image_format   = image_format;
+   
+   return dfiasco;
+}
+
+static void
+free_dfiasco (dfiasco_t *dfiasco)
+/*
+ *  FIASCO decoder destructor:
+ *  Free memory of given 'decoder' struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'video' struct is discarded.
+ */
+{
+   Free (dfiasco);
+}
+
+static dfiasco_t *
+cast_dfiasco (fiasco_decoder_t *dfiasco)
+/*
+ *  Cast pointer `dfiasco' to type dfiasco_t.
+ *  Check whether `dfiasco' is a valid object of type dfiasco_t.
+ *
+ *  Return value:
+ *	pointer to dfiasco_t struct on success
+ *      NULL otherwise
+ */
+{
+   dfiasco_t *this = (dfiasco_t *) dfiasco->private;
+   if (this)
+   {
+      if (!streq (this->id, "DFIASCO"))
+      {
+	 set_error (_("Parameter `dfiasco' doesn't match required type."));
+	 return NULL;
+      }
+   }
+   else
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "dfiasco");
+   }
+
+   return this;
+}
diff --git a/converter/other/fiasco/codec/dfiasco.h b/converter/other/fiasco/codec/dfiasco.h
new file mode 100644
index 00000000..bcc3c7f9
--- /dev/null
+++ b/converter/other/fiasco/codec/dfiasco.h
@@ -0,0 +1,38 @@
+/*
+ *  dfiasco.h
+ *		
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/15 18:00:53 $
+ *  $Author: hafner $
+ *  $Revision: 5.2 $
+ *  $State: Exp $
+ */
+
+#ifndef _DFIASCO_H
+#define _DFIASCO_H
+
+#include "types.h"
+#include "bit-io.h"
+#include "decoder.h"
+#include "image.h"
+#include "wfa.h"
+
+typedef struct dfiasco
+{
+   char       id [8];
+   wfa_t     *wfa;
+   video_t   *video;
+   bitfile_t *input;
+   int	      enlarge_factor;
+   int        smoothing;
+   format_e   image_format;
+} dfiasco_t;
+
+#endif /* not _DFIASCO_H */
+
diff --git a/converter/other/fiasco/codec/domain-pool.c b/converter/other/fiasco/codec/domain-pool.c
new file mode 100644
index 00000000..09f854a6
--- /dev/null
+++ b/converter/other/fiasco/codec/domain-pool.c
@@ -0,0 +1,986 @@
+/*
+ *  domain-pool.c:  Domain pool management (probability model)
+ *
+ *  Written by:     Ullrich Hafner
+ *      
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include <math.h>
+
+#if STDC_HEADERS
+#   include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#if HAVE_STRING_H
+#   include <string.h>
+#else /* not HAVE_STRING_H */
+#   include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "misc.h"
+#include "cwfa.h"
+#include "wfalib.h"
+#include "domain-pool.h"
+
+/*
+ *  Domain pool model interface:
+ *  Implementing the domain pool model interface requires the
+ *  following steps: 
+ *  - Add a constructor that initializes the domain_pool_t structure
+ *  - Allocate new model with default_alloc() 
+ *  - Fill the dp_array_t domain_pools array with constructor and name
+ *  - Write code for methods bits() and generate()
+ *  - Either use default functions for remaining methods or override them
+ *  The new model is automatically registered at the command line.
+ */
+
+/*****************************************************************************
+                                          
+                  local variables
+                  
+*****************************************************************************/
+
+static real_t *matrix_0 = NULL;
+static real_t *matrix_1 = NULL;
+
+/*****************************************************************************
+                        non-adaptive domain pool
+*****************************************************************************/
+
+static void
+qac_chroma (unsigned max_domains, const wfa_t *wfa, void *model);
+static bool_t
+qac_append (unsigned new_state, unsigned level, const wfa_t *wfa, void *model);
+static void
+qac_update (const word_t *domains, const word_t *used_domains,
+            unsigned level, int y_state, const wfa_t *wfa, void *model);
+static real_t
+qac_bits (const word_t *domains, const word_t *used_domains,
+          unsigned level, int y_state, const wfa_t *wfa, const void *model);
+static word_t *
+qac_generate (unsigned level, int y_state, const wfa_t *wfa,
+              const void *model);
+static void *
+qac_model_duplicate (const void *src);
+static void
+qac_model_free (void *model);
+static void *
+qac_model_alloc (unsigned max_domains);
+static domain_pool_t *
+alloc_qac_domain_pool (unsigned max_domains, unsigned max_edges,
+                       const wfa_t *wfa);
+
+/*****************************************************************************
+              run length encoding pool
+*****************************************************************************/
+
+static domain_pool_t *
+alloc_rle_no_chroma_domain_pool (unsigned max_domains, unsigned max_edges,
+                                 const wfa_t *wfa);
+static void
+rle_chroma (unsigned max_domains, const wfa_t *wfa, void *model);
+static bool_t
+rle_append (unsigned new_state, unsigned level, const wfa_t *wfa, void *model);
+static void
+rle_update (const word_t *domains, const word_t *used_domains,
+            unsigned level, int y_state, const wfa_t *wfa, void *model);
+static real_t
+rle_bits (const word_t *domains, const word_t *used_domains,
+          unsigned level, int y_state, const wfa_t *wfa, const void *model);
+static word_t *
+rle_generate (unsigned level, int y_state, const wfa_t *wfa,
+              const void *model);
+static void *
+rle_model_duplicate (const void *src);
+static void
+rle_model_free (void *model);
+static void *
+rle_model_alloc (unsigned max_domains);
+static domain_pool_t *
+alloc_rle_domain_pool (unsigned max_domains, unsigned max_edges,
+                       const wfa_t *wfa);
+
+/*****************************************************************************
+              const domain pool
+*****************************************************************************/
+
+static real_t
+const_bits (const word_t *domains, const word_t *used_domains,
+            unsigned level, int y_state, const wfa_t *wfa, const void *model);
+static word_t *
+const_generate (unsigned level, int y_state, const wfa_t *wfa,
+                const void *model);
+static domain_pool_t *
+alloc_const_domain_pool (unsigned max_domains, unsigned max_edges,
+                         const wfa_t *wfa);
+
+/*****************************************************************************
+              basis domain pool
+*****************************************************************************/
+
+static domain_pool_t *
+alloc_basis_domain_pool (unsigned max_domains, unsigned max_edges,
+                         const wfa_t *wfa);
+
+/*****************************************************************************
+              uniform distribution pool
+*****************************************************************************/
+
+static real_t
+uniform_bits (const word_t *domains, const word_t *used_domains,
+              unsigned level, int y_state, const wfa_t *wfa,
+              const void *model);
+static word_t *
+uniform_generate (unsigned level, int y_state, const wfa_t *wfa,
+                  const void *model);
+static domain_pool_t *
+alloc_uniform_domain_pool (unsigned max_domains, unsigned max_edges,
+                           const wfa_t *wfa);
+
+/*****************************************************************************
+              default functions
+*****************************************************************************/
+
+static void
+init_matrix_probabilities (void);
+static void
+default_chroma (unsigned max_domains, const wfa_t *wfa, void *model);
+static bool_t
+default_append (unsigned new_state, unsigned level,
+                const wfa_t *wfa, void *model);
+static void
+default_update (const word_t *domains, const word_t *used_domains,
+                unsigned level, int y_state, const wfa_t *wfa, void *model);
+static void
+default_free (domain_pool_t *pool);
+static void
+default_model_free (void *model);
+static void *
+default_model_alloc (unsigned max_domains);
+static void *
+default_model_duplicate (const void *src);
+static domain_pool_t *
+default_alloc (void);
+
+/*****************************************************************************
+
+                public code
+  
+*****************************************************************************/
+
+typedef struct dp_array
+{
+    const char       *identifier;
+    domain_pool_t *(*function) (unsigned max_domains, unsigned max_edges,
+                                const wfa_t *wfa);
+} dp_array_t;
+
+dp_array_t const domain_pools[] = {{"adaptive", alloc_qac_domain_pool},
+                                   {"constant",   alloc_const_domain_pool}, 
+                                   {"basis",      alloc_basis_domain_pool},
+                                   {"uniform",    alloc_uniform_domain_pool},
+                                   {"rle",        alloc_rle_domain_pool},
+                                   {"rle-no-chroma",  alloc_rle_no_chroma_domain_pool},
+                                   {NULL,     NULL}};
+
+domain_pool_t *
+alloc_domain_pool (const char *domain_pool_name, unsigned max_domains,
+                   unsigned max_edges, const wfa_t *wfa)
+/*
+ *  Allocate a new domain pool identified by the string
+ *  'domain_pool_name'.  Maximum number of domain images (each one
+ *  represented by one state of the given 'wfa') is specified by
+ *  'max_domains'. 
+ * 
+ *  Return value:
+ *  pointer to the allocated domain pool
+ *
+ *  Note:
+ *      refer to 'domain-pool.h' for a short description of the member functions.
+ */
+{
+    unsigned n;
+   
+    if (!max_domains)
+    {
+        warning ("Can't generate empty domain pool. "
+                 "Using at least DC component.");
+        max_domains = 1;
+    }
+   
+    for (n = 0; domain_pools [n].identifier; n++) /* step through all id's */
+        if (strcaseeq (domain_pools [n].identifier, domain_pool_name)) 
+            return domain_pools [n].function (max_domains, max_edges, wfa);
+
+    warning ("Can't initialize domain pool '%s'. Using default value '%s'.",
+             domain_pool_name, domain_pools [0].identifier);
+
+    return domain_pools [0].function (max_domains, max_edges, wfa);
+}
+
+/*****************************************************************************
+
+                private code
+  
+*****************************************************************************/
+
+/*****************************************************************************
+              adaptive domain pool
+*****************************************************************************/
+
+typedef struct qac_model
+{
+    word_t   *index;         /* probability of domains */
+    word_t   *states;            /* mapping states -> domains */
+    u_word_t  y_index;           /* pointer to prob of Y domain */
+    u_word_t  n;             /* number of domains in the pool */
+    u_word_t  max_domains;       /* max. number of domains */
+} qac_model_t;
+
+static domain_pool_t *
+alloc_qac_domain_pool (unsigned max_domains, unsigned max_edges,
+                       const wfa_t *wfa)
+/*
+ *  Domain pool with state images {0, ..., 'max_domains').
+ *  Underlying probability model: quasi arithmetic coding of columns.
+ */
+{
+    domain_pool_t *pool;
+    unsigned   state;
+   
+    pool                  = default_alloc ();
+    pool->model           = qac_model_alloc (max_domains);
+    pool->generate        = qac_generate;
+    pool->bits            = qac_bits;
+    pool->update          = qac_update;
+    pool->append          = qac_append;
+    pool->chroma      = qac_chroma;
+    pool->model_free      = qac_model_free;
+    pool->model_duplicate = qac_model_duplicate;
+   
+    for (state = 0; state < wfa->basis_states; state++)
+        if (usedomain (state, wfa))
+            qac_append (state, -1, wfa, pool->model);
+
+    return pool;
+}
+
+static void *
+qac_model_alloc (unsigned max_domains)
+{
+    qac_model_t *model;
+
+    init_matrix_probabilities ();
+
+    model          = Calloc (1, sizeof (qac_model_t));
+    model->index       = Calloc (max_domains, sizeof (word_t));
+    model->states      = Calloc (max_domains, sizeof (word_t));
+    model->y_index     = 0;
+    model->n       = 0;
+    model->max_domains = max_domains;
+
+    return model;
+}
+
+static void
+qac_model_free (void *model)
+{
+    Free (((qac_model_t *) model)->index);
+    Free (((qac_model_t *) model)->states);
+    Free (model);
+}
+
+static void *
+qac_model_duplicate (const void *src)
+{
+    qac_model_t       *qdst;
+    const qac_model_t *qsrc = (qac_model_t *) src;
+
+    qdst      = qac_model_alloc (qsrc->max_domains);
+    qdst->y_index = qsrc->y_index;
+    qdst->n       = qsrc->n;
+   
+    memcpy (qdst->index, qsrc->index, qsrc->n * sizeof (word_t));
+    memcpy (qdst->states, qsrc->states, qsrc->n * sizeof (word_t));
+
+    return qdst;
+}
+
+static word_t *
+qac_generate (unsigned level, int y_state, const wfa_t *wfa, const void *model)
+{
+    word_t      *domains;
+    unsigned n;
+    qac_model_t *qac_model     = (qac_model_t *) model;
+    bool_t   y_state_is_domain = NO;
+
+    if (y_state >= 0 && !usedomain (y_state, wfa)) /* don't use y-state */
+        y_state = -1;
+   
+    domains = Calloc (qac_model->n + 2, sizeof (word_t));
+
+    memcpy (domains, qac_model->states, qac_model->n * sizeof (word_t));
+
+    for (n = 0; n < qac_model->n; n++)
+        if (domains [n] == y_state)   /* match */
+            y_state_is_domain = YES;       
+
+    if (y_state_is_domain)
+        domains [qac_model->n] = -1;  /* end marker */
+    else
+    {
+        domains [qac_model->n]     = y_state; /* additional y-state */
+        domains [qac_model->n + 1] = -1;  /* end marker */
+    }
+
+    return domains;
+}
+
+static real_t
+qac_bits (const word_t *domains, const word_t *used_domains,
+          unsigned level, int y_state, const wfa_t *wfa, const void *model)
+{
+    int      domain;         /* counter */
+    real_t   bits      = 0;      /* bit rate R */
+    qac_model_t *qac_model = (qac_model_t *) model; /* probability model */
+
+    if (y_state >= 0 && !usedomain (y_state, wfa)) /* don't use y-state */
+        y_state = -1;
+
+    for (domain = 0; domain < qac_model->n; domain++)
+        if (qac_model->states [domain] != y_state)
+            bits += matrix_0 [qac_model->index [domain]];
+    if (y_state >= 0)
+        bits += matrix_0 [qac_model->y_index];
+   
+    if (used_domains != NULL)
+    {
+        unsigned edge;
+      
+        for (edge = 0; isedge (domain = used_domains [edge]); edge++)
+            if (domains [domain] == y_state)
+            {
+                bits -= matrix_0 [qac_model->y_index];
+                bits += matrix_1 [qac_model->y_index];
+            }
+            else
+            {
+                bits -= matrix_0 [qac_model->index [domain]];
+                bits += matrix_1 [qac_model->index [domain]];
+            }
+    } 
+   
+    return bits;
+}
+
+static void
+qac_update (const word_t *domains, const word_t *used_domains,
+            unsigned level, int y_state, const wfa_t *wfa, void *model)
+{
+    int      domain;
+    unsigned edge;
+    bool_t   used_y_state      = NO;
+    qac_model_t *qac_model     = (qac_model_t *) model;
+    bool_t   y_state_is_domain = NO;
+   
+    if (y_state >= 0 && !usedomain (y_state, wfa)) /* don't use y-state */
+        y_state = -1;
+
+    for (domain = 0; domain < qac_model->n; domain++)
+    {
+        qac_model->index [domain]++;  /* mark domains unused. */
+        if (qac_model->states [domain] == y_state) /* match */
+            y_state_is_domain = YES;       
+    }
+   
+    for (edge = 0; isedge (domain = used_domains [edge]); edge++)
+        if (domains [domain] == y_state) /* chroma coding */
+        {
+            if (y_state_is_domain)
+                qac_model->index [domain]--; /* undo */
+            qac_model->y_index >>= 1;
+            used_y_state = YES;
+        }
+        else              /* luminance coding */
+        {
+            qac_model->index [used_domains [edge]]--; /* undo */
+            qac_model->index [used_domains [edge]] >>= 1;      
+        }
+
+    if (y_state >= 0 && !used_y_state)
+        qac_model->y_index++;     /* update y-state model */
+   
+    for (domain = 0; domain < qac_model->n; domain++)
+        if (qac_model->index [domain] > 1020) /* check for overflow */
+            qac_model->index [domain] = 1020; 
+    if (qac_model->y_index > 1020)   /* check for overflow */
+        qac_model->y_index = 1020; 
+}
+
+static bool_t
+qac_append (unsigned new_state, unsigned level, const wfa_t *wfa, void *model)
+{
+    qac_model_t  *qac_model = (qac_model_t *) model; /* probability model */
+   
+    if (qac_model->n >= qac_model->max_domains)
+        return NO;            /* don't use state in domain pool */
+    else
+    {
+        qac_model->index [qac_model->n]
+            = qac_model->n > 0 ? qac_model->index [qac_model->n - 1] : 0;
+        qac_model->states [qac_model->n] = new_state;
+        qac_model->n++;
+
+        return YES;           /* state will be used in domain pool */
+    }
+}
+
+static void
+qac_chroma (unsigned max_domains, const wfa_t *wfa, void *model)
+{
+    qac_model_t *qac_model = (qac_model_t *) model; /* probability model */
+   
+    if (max_domains < qac_model->n)  /* choose most probable domains */
+    {
+        word_t   *domains;
+        unsigned  n, new, old;
+        word_t   *states = Calloc (max_domains, sizeof (word_t));
+        word_t   *index  = Calloc (max_domains, sizeof (word_t));
+   
+        domains = compute_hits (wfa->basis_states, wfa->states - 1,
+                                max_domains, wfa);
+        for (n = 0; n < max_domains && domains [n] >= 0; n++)
+            states [n] = domains [n];
+        max_domains = min (max_domains, n);
+        Free (domains);
+
+        for (old = 0, new = 0; new < max_domains && old < qac_model->n; old++)
+            if (qac_model->states [old] == states [new])
+                index [new++] = qac_model->index [old];
+
+        Free (qac_model->states);
+        Free (qac_model->index);
+        qac_model->states      = states;
+        qac_model->index       = index;
+        qac_model->n           = max_domains;
+        qac_model->max_domains = max_domains;
+    }
+    qac_model->y_index     = 0;
+    qac_model->max_domains = qac_model->n;
+}
+
+/*****************************************************************************
+              const domain pool
+*****************************************************************************/
+
+static domain_pool_t *
+alloc_const_domain_pool (unsigned max_domains, unsigned max_edges,
+                         const wfa_t *wfa)
+/*
+ *  Domain pool with state image 0 (constant function f(x, y) = 1).
+ *  No probability model is used.
+ */
+{
+    domain_pool_t *pool;
+   
+    pool           = default_alloc ();   
+    pool->generate = const_generate;
+    pool->bits     = const_bits;
+   
+    return pool;
+}
+
+static word_t *
+const_generate (unsigned level, int y_state, const wfa_t *wfa,
+                const void *model)
+{
+    word_t *domains = Calloc (2, sizeof (word_t));
+   
+    domains [0] = 0;
+    domains [1] = -1;
+   
+    return domains;
+}
+
+static real_t
+const_bits (const word_t *domains, const word_t *used_domains,
+            unsigned level, int y_state, const wfa_t *wfa, const void *model)
+{
+    return 0;                /* 0 bits,
+                                either we have a lc or not */
+}
+
+/*****************************************************************************
+                basis domain pool
+*****************************************************************************/
+
+static domain_pool_t *
+alloc_basis_domain_pool (unsigned max_domains, unsigned max_edges,
+                         const wfa_t *wfa)
+/*
+ *  Domain pool with state images {0, ..., 'basis_states' - 1).
+ *  Underlying probability model: quasi arithmetic coding of columns.
+ *  I.e. domain pool = qac_domainpool ('max_domains' == wfa->basis_states)
+ */
+{
+    return alloc_qac_domain_pool (wfa->basis_states, max_edges, wfa);
+}
+
+/*****************************************************************************
+              uniform-distribution pool
+*****************************************************************************/
+
+static domain_pool_t *
+alloc_uniform_domain_pool (unsigned max_domains, unsigned max_edges,
+                           const wfa_t *wfa)
+/*
+ *  Domain pool with state images {0, ..., 'max_domains').
+ *  Underlying probability model: uniform distribution.
+ */
+{
+    domain_pool_t *pool;
+   
+    pool           = default_alloc ();   
+    pool->generate = uniform_generate;
+    pool->bits     = uniform_bits;
+   
+    return pool;
+}
+
+static word_t *
+uniform_generate (unsigned level, int y_state, const wfa_t *wfa,
+                  const void *model)
+{
+    unsigned  state, n;
+    word_t   *domains = Calloc (wfa->states + 1, sizeof (word_t));
+
+    for (state = 0, n = 0; state < wfa->states; state++)
+        if (usedomain (state, wfa))
+            domains [n++] = state;
+    domains [n] = -1;
+   
+    return domains;
+}
+ 
+static real_t
+uniform_bits (const word_t *domains, const word_t *used_domains,
+              unsigned level, int y_state, const wfa_t *wfa, const void *model)
+{
+    unsigned state, n;
+    real_t   bits = 0;
+   
+    for (state = 0, n = 0; state < wfa->states; state++)
+        if (usedomain (state, wfa))
+            n++;
+
+    bits = - n * log2 ((n - 1) / (real_t) n);
+
+    if (used_domains != NULL)
+    {
+        int edge;
+      
+        for (edge = 0; isedge (used_domains [edge]); edge++)
+            bits -= log2 (1.0 / n);
+    }
+
+    return bits;
+}
+
+/*****************************************************************************
+              run length encoding pool
+*****************************************************************************/
+
+typedef struct rle_model
+{
+    word_t   count [MAXEDGES + 1];
+    u_word_t total;
+    u_word_t n;
+    u_word_t max_domains;
+    u_word_t y_index;        /* pointer to prob of Y domain */
+    word_t      *states;         /* mapping states -> domains */
+    qac_model_t *domain_0;
+} rle_model_t;
+
+static domain_pool_t *
+alloc_rle_domain_pool (unsigned max_domains, unsigned max_edges,
+                       const wfa_t *wfa)
+/*
+ *  Domain pool with state images {0, ..., 'max_domains').
+ *  Underlying probability model: rle 
+ */
+{
+    domain_pool_t *pool;
+    unsigned   state;
+   
+    pool                  = default_alloc ();    
+    pool->model           = rle_model_alloc (max_domains);
+    pool->model_free      = rle_model_free;
+    pool->model_duplicate = rle_model_duplicate;
+    pool->generate        = rle_generate;
+    pool->update          = rle_update;
+    pool->bits            = rle_bits;
+    pool->append          = rle_append;
+    pool->chroma          = rle_chroma;
+
+    for (state = 0; state < wfa->basis_states; state++)
+        if (usedomain (state, wfa))
+            rle_append (state, -1, wfa, pool->model);
+
+    return pool;
+}
+
+static void *
+rle_model_alloc (unsigned max_domains)
+{
+    unsigned m;
+    rle_model_t *model = Calloc (1, sizeof (rle_model_t));
+   
+    for (m = model->total = 0; m < MAXEDGES + 1; m++, model->total++)
+        model->count [m] = 1;
+
+    model->domain_0    = qac_model_alloc (1);
+    model->states      = Calloc (max_domains, sizeof (word_t));
+    model->n       = 0;
+    model->y_index     = 0;
+    model->max_domains = max_domains;
+   
+    return model;
+}
+
+static void
+rle_model_free (void *model)
+{
+    qac_model_free (((rle_model_t *) model)->domain_0);
+    Free (((rle_model_t *) model)->states);
+    Free (model);
+}
+
+static void *
+rle_model_duplicate (const void *src)
+{
+    const rle_model_t *rle_src = (rle_model_t *) src;
+    rle_model_t       *model   = Calloc (1, sizeof (rle_model_t));
+
+    model->domain_0    = qac_model_duplicate (rle_src->domain_0);
+    model->n       = rle_src->n;
+    model->max_domains = rle_src->max_domains;
+    model->states      = Calloc (model->max_domains, sizeof (word_t));
+    model->total       = rle_src->total;
+    model->y_index     = rle_src->y_index;
+   
+    memcpy (model->states, rle_src->states,
+            model->max_domains * sizeof (word_t));
+    memcpy (model->count, rle_src->count,
+            (MAXEDGES + 1) * sizeof (word_t));
+   
+    return model;
+}
+
+static word_t *
+rle_generate (unsigned level, int y_state, const wfa_t *wfa, const void *model)
+{
+    word_t      *domains;
+    unsigned n;
+    rle_model_t *rle_model     = (rle_model_t *) model;
+    bool_t   y_state_is_domain = NO;
+   
+    if (y_state >= 0 && !usedomain (y_state, wfa)) /* don't use y-state */
+        y_state = -1;
+   
+    domains = Calloc (rle_model->n + 2, sizeof (word_t));
+
+    memcpy (domains, rle_model->states, rle_model->n * sizeof (word_t));
+
+    for (n = 0; n < rle_model->n; n++)
+        if (domains [n] == y_state)   /* match */
+            y_state_is_domain = YES;       
+
+    if (y_state_is_domain)
+        domains [rle_model->n] = -1;  /* end marker */
+    else
+    {
+        domains [rle_model->n]     = y_state; /* additional y-state */
+        domains [rle_model->n + 1] = -1;  /* end marker */
+    }
+
+    return domains;
+}
+
+static real_t
+rle_bits (const word_t *domains, const word_t *used_domains,
+          unsigned level, int y_state, const wfa_t *wfa, const void *model)
+{
+    unsigned edge;
+    unsigned n     = 0;
+    real_t   bits      = 0;
+    word_t   sorted [MAXEDGES + 1];
+    rle_model_t *rle_model = (rle_model_t *) model;
+    unsigned last;
+    int      into;
+   
+    if (y_state >= 0 && !usedomain (y_state, wfa)) /* don't use y-state */
+        y_state = -1;
+
+    if (used_domains)
+    {
+        word_t domain;
+      
+        if (y_state >= 0)
+            bits += matrix_0 [rle_model->y_index];
+      
+        for (edge = n = 0; isedge (domain = used_domains [edge]); edge++)
+            if (domains [domain] != y_state)
+                sorted [n++] = used_domains [edge];
+            else
+            {
+                bits -= matrix_0 [rle_model->y_index];
+                bits += matrix_1 [rle_model->y_index];
+            }
+      
+        if (n > 1)
+            qsort (sorted, n, sizeof (word_t), sort_asc_word);
+    }
+
+    bits = - log2 (rle_model->count [n] / (real_t) rle_model->total);
+    if (used_domains && n && sorted [0] == 0)
+    {
+        word_t array0 [2] = {0, NO_EDGE};
+        bits += qac_bits (array0, array0, level, y_state, wfa, rle_model->domain_0);
+    }
+    else
+    {
+        word_t array0 [2] = {NO_EDGE};
+        bits += qac_bits (array0, array0, level, y_state, wfa, rle_model->domain_0);
+    }
+   
+    last = 1;
+    for (edge = 0; edge < n; edge++)
+        if ((into = sorted [edge]) && rle_model->n - 1 - last)
+        {
+            bits += bits_bin_code (into - last, rle_model->n - 1 - last);
+            last  = into + 1;
+        }
+   
+    return bits;
+}
+
+static void
+rle_update (const word_t *domains, const word_t *used_domains,
+            unsigned level, int y_state, const wfa_t *wfa, void *model)
+{
+    rle_model_t *rle_model  = (rle_model_t *) model;
+    bool_t   state_0    = NO, state_y = NO;
+    word_t   array0 [2] = {0, NO_EDGE};
+    unsigned     edge = 0;
+   
+    if (y_state >= 0 && !usedomain (y_state, wfa)) /* don't use y-state */
+        y_state = -1;
+
+    if (used_domains)
+    {
+        word_t   domain;
+      
+        for (edge = 0; isedge (domain = used_domains [edge]); edge++)
+            if (domains [domain] == 0)
+                state_0 = YES;
+            else if (domains [domain] == y_state)
+                state_y = YES;
+    }
+   
+    rle_model->count [edge]++;
+    rle_model->total++;
+
+    qac_update (array0, array0 + (state_0 ? 0 : 1), level, y_state, wfa,
+                rle_model->domain_0);
+
+    if (state_y)
+        rle_model->y_index >>= 1;
+    else
+        rle_model->y_index++;
+    if (rle_model->y_index > 1020)   /* check for overflow */
+        rle_model->y_index = 1020; 
+}
+
+static bool_t
+rle_append (unsigned new_state, unsigned level, const wfa_t *wfa, void *model)
+{
+    rle_model_t *rle_model = (rle_model_t *) model; /* probability model */
+   
+    if (rle_model->n >= rle_model->max_domains)
+        return NO;            /* don't use state in domain pool */
+    else
+    {
+        rle_model->states [rle_model->n] = new_state;
+        rle_model->n++;
+
+        if (new_state == 0)
+        {
+            assert (rle_model->n == 1);
+            qac_append (0, -1, wfa, rle_model->domain_0);
+        }
+      
+        return YES;           /* state will be used in domain pool */
+    }
+}
+
+static void
+rle_chroma (unsigned max_domains, const wfa_t *wfa, void *model)
+{
+    rle_model_t *rle_model = (rle_model_t *) model; /* probability model */
+   
+    if (max_domains < rle_model->n)  /* choose most probable domains */
+    {
+        unsigned  n;
+        word_t   *states  = Calloc (max_domains, sizeof (word_t));
+        word_t   *domains = compute_hits (wfa->basis_states, wfa->states - 1,
+                                          max_domains, wfa);
+      
+        for (n = 0; n < max_domains && domains [n] >= 0; n++)
+            states [n] = domains [n];
+
+        assert (states [0] == 0);
+        max_domains = min (max_domains, n);
+        Free (domains);
+
+        Free (rle_model->states);
+        rle_model->states = states;
+        rle_model->n      = max_domains;
+    }
+    rle_model->y_index     = 0;
+    rle_model->max_domains = rle_model->n;
+}
+
+/*****************************************************************************
+         run length encoding pool no special chroma pool
+*****************************************************************************/
+
+static domain_pool_t *
+alloc_rle_no_chroma_domain_pool (unsigned max_domains, unsigned max_edges,
+                                 const wfa_t *wfa)
+/*
+ *  Domain pool with state images {0, ..., 'max_domains').
+ *  Underlying probability model: rle 
+ *  Domain pool is not changed for chroma bands
+ */
+{
+    domain_pool_t *pool = alloc_rle_domain_pool (max_domains, max_edges, wfa);
+   
+    pool->chroma = default_chroma;
+
+    return pool;
+}
+
+/*****************************************************************************
+              default functions (see domain-pool.h)
+*****************************************************************************/
+
+static domain_pool_t *
+default_alloc (void)
+{
+    domain_pool_t *pool;
+
+    pool                  = Calloc (1, sizeof (domain_pool_t));
+    pool->model           = default_model_alloc(0);
+    pool->generate        = NULL;
+    pool->bits            = NULL;
+    pool->update          = default_update;
+    pool->append          = default_append;
+    pool->chroma          = default_chroma;
+    pool->free            = default_free;
+    pool->model_free      = default_model_free;
+    pool->model_duplicate = default_model_duplicate;
+   
+    return pool;
+}
+
+static void *
+default_model_duplicate (const void *src)
+{
+    return NULL;
+}
+
+static void *
+default_model_alloc (unsigned max_domains)
+{
+    return NULL;
+}
+
+static void
+default_model_free (void *model)
+{
+    if (model)
+        Free (model);
+}
+
+static void
+default_free (domain_pool_t *pool)
+{
+    pool->model_free (pool->model);
+    Free (pool);
+}
+
+static void
+default_update (const word_t *domains, const word_t *used_domains,
+                unsigned level, int y_state, const wfa_t *wfa, void *model)
+{
+    return;              /* nothing to do */
+}
+
+static bool_t
+default_append (unsigned new_state, unsigned level,
+                const wfa_t *wfa, void *model)
+{
+    return YES;              /* use every state in lin comb */
+}
+
+static void
+default_chroma (unsigned max_domains, const wfa_t *wfa, void *model)
+{
+    return;              /* don't alter domain pool */
+}
+
+static void
+init_matrix_probabilities (void)
+/*
+ *  Compute the information contents of matrix element '0' and '1' for
+ *  each possible probability index 0, ... ,  1023. These values are
+ *  obtained from the probability model in the quasi arithmetic
+ *  coding module.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *  local arrays matrix_0 and matrix_1 are initialized if not already done.
+ */
+{
+    if (matrix_0 == NULL || matrix_1 == NULL)
+    {
+        unsigned index;           
+        unsigned n, exp;
+      
+        matrix_0 = Calloc (1 << (MAX_PROB + 1), sizeof (real_t));
+        matrix_1 = Calloc (1 << (MAX_PROB + 1), sizeof (real_t));
+   
+        for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++)
+            for (exp = 0; exp < (unsigned) 1 << n; exp++, index++)
+            {
+                matrix_1 [index] = -log2 (1 / (real_t) (1 << n));
+                matrix_0 [index] = -log2 (1 - 1 / (real_t) (1 << n));
+            }
+    }
+}
diff --git a/converter/other/fiasco/codec/domain-pool.h b/converter/other/fiasco/codec/domain-pool.h
new file mode 100644
index 00000000..d1488779
--- /dev/null
+++ b/converter/other/fiasco/codec/domain-pool.h
@@ -0,0 +1,75 @@
+/*
+ *  domain-pool.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _DOMAIN_POOL_H
+#define _DOMAIN_POOL_H
+
+#include "cwfa.h"
+#include "types.h"
+
+typedef struct domain_pool
+{
+   void	  *model;			/* probability model */
+   word_t *(*generate) (unsigned level, int y_state, const wfa_t *wfa,
+			const void  *model);
+   /*
+    *  Generate set of domain images which may be used for an approximation.
+    *  Use parameters 'level', 'y_state' and 'wfa' to make the decision.
+    */
+   real_t (*bits) (const word_t *domains, const word_t *used_domains,
+		   unsigned level, int y_state, const wfa_t *wfa,
+		   const void *model);
+   /*
+    *  Compute bit-rate of a range approximation with domains given by
+    *  the -1 terminated list 'used_domains'.
+    */
+   void	  (*update) (const word_t *domains, const word_t *used_domains,
+		     unsigned level, int y_state, const wfa_t *wfa,
+		     void *model);
+   /*
+    *  Update the probability model according to the chosen approximation.
+    *  (given by the -1 terminated list 'used_domains').
+    */
+   bool_t (*append) (unsigned state, unsigned level, const wfa_t *wfa,
+		     void *model);
+   /*
+    *  Try to append a new state to the domain pool.
+    */
+   void	  (*chroma) (unsigned max_domains, const wfa_t *wfa, void *model);
+   /*
+    *  Derive a new domain pool that will be used for chroma channel
+    *  coding 
+    */
+   void   (*free) (struct domain_pool *pool);
+   /*
+    *  Discard the given domain pool struct.
+    */
+   void   (*model_free)	(void *model);
+   /*
+    *  Free given probability model.
+    */
+   void   *(*model_duplicate) (const void *src);
+   /*
+    *  Duplicate the given probability model (i.e. alloc and copy).
+    */
+} domain_pool_t;
+
+domain_pool_t *
+alloc_domain_pool (const char *domain_pool_name, unsigned max_domains,
+		   unsigned max_edges, const wfa_t *wfa);
+
+#endif /* not _DOMAIN_POOL_H */
+
diff --git a/converter/other/fiasco/codec/ip.c b/converter/other/fiasco/codec/ip.c
new file mode 100644
index 00000000..caa97baf
--- /dev/null
+++ b/converter/other/fiasco/codec/ip.c
@@ -0,0 +1,324 @@
+/*
+ *  ip.c:		Computation of inner products
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "cwfa.h"
+#include "control.h"
+#include "ip.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static real_t 
+standard_ip_image_state (unsigned address, unsigned level, unsigned domain,
+			 const coding_t *c);
+static real_t 
+standard_ip_state_state (unsigned domain1, unsigned domain2, unsigned level,
+			 const coding_t *c);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+real_t 
+get_ip_image_state (unsigned image, unsigned address, unsigned level,
+		    unsigned domain, const coding_t *c)
+/*
+ *  Return value:
+ *	Inner product between 'image' ('address') and
+ *      'domain' at given 'level' 
+ */
+{
+   if (level <= c->options.images_level)
+   {
+      /*
+       *  Compute the inner product in the standard way by multiplying 
+       *  the pixel-values of the given domain and range image.
+       */ 
+      return standard_ip_image_state (address, level, domain, c);
+   }
+   else 
+   {
+      /*
+       *  Use the already computed inner products stored in 'ip_images_states'
+       */
+      return c->ip_images_state [domain][image];
+   }
+}
+
+void 
+compute_ip_images_state (unsigned image, unsigned address, unsigned level,
+			 unsigned n, unsigned from,
+			 const wfa_t *wfa, coding_t *c)
+/*
+ *  Compute the inner products between all states
+ *  'from', ... , 'wfa->max_states' and the range images 'image'
+ *  (and childs) up to given level.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	inner product tables 'c->ip_images_states' are updated
+ */ 
+{
+   if (level > c->options.images_level) 
+   {
+      unsigned state, label;
+
+      if (level > c->options.images_level + 1)	/* recursive computation */
+	 compute_ip_images_state (MAXLABELS * image + 1, address * MAXLABELS,
+				  level - 1, MAXLABELS * n, from, wfa, c);
+      
+      /*
+       *  Compute inner product <f, Phi_i>
+       */
+      for (label = 0; label < MAXLABELS; label++)
+	 for (state = from; state < wfa->states; state++)
+	    if (need_image (state, wfa))
+	    {
+	       unsigned  edge, count;
+	       int     	 domain;
+	       real_t 	*dst, *src;
+	       
+	       if (ischild (domain = wfa->tree [state][label]))
+	       {
+		  if (level > c->options.images_level + 1)
+		  {
+		     dst = c->ip_images_state [state] + image;
+		     src = c->ip_images_state [domain]
+			   + image * MAXLABELS + label + 1;
+		     for (count = n; count; count--, src += MAXLABELS)
+			*dst++ += *src;
+		  }
+		  else
+		  {
+		     unsigned newadr = address * MAXLABELS + label;
+		     
+		     dst = c->ip_images_state [state] + image;
+		     
+		     for (count = n; count; count--, newadr += MAXLABELS)
+			*dst++ += standard_ip_image_state (newadr, level - 1,
+							   domain, c);
+		  }
+	       }
+	       for (edge = 0; isedge (domain = wfa->into [state][label][edge]);
+		    edge++)
+	       {
+		  real_t weight = wfa->weight [state][label][edge];
+		  
+		  if (level > c->options.images_level + 1)
+		  {
+		     dst = c->ip_images_state [state] + image;
+		     src = c->ip_images_state [domain]
+			   + image * MAXLABELS + label + 1;
+		     for (count = n; count; count--, src += MAXLABELS)
+			*dst++ += *src * weight;
+		  }
+		  else
+		  {
+		     unsigned newadr = address * MAXLABELS + label;
+
+		     dst = c->ip_images_state [state] + image;
+		     
+		     for (count = n; count; count--, newadr += MAXLABELS)
+			*dst++ += weight *
+				  standard_ip_image_state (newadr, level - 1,
+							   domain, c);
+		  }
+	       }
+	    }
+   }
+}
+
+real_t 
+get_ip_state_state (unsigned domain1, unsigned domain2, unsigned level,
+		    const coding_t *c)
+/*
+ *  Return value:
+ *	Inner product between 'domain1' and 'domain2' at given 'level'.
+ */
+{
+   if (level <= c->options.images_level)
+   {
+      /*
+       *  Compute the inner product in the standard way by multiplying 
+       *  the pixel-values of both state-images
+       */ 
+      return standard_ip_state_state (domain1, domain2, level, c);
+   }
+   else 
+   {
+      /*
+       *  Use already computed inner products stored in 'ip_images_states'
+       */
+      if (domain2 < domain1)
+	 return c->ip_states_state [domain1][level][domain2];
+      else
+	 return c->ip_states_state [domain2][level][domain1];
+   }
+}
+
+void 
+compute_ip_states_state (unsigned from, unsigned to,
+			 const wfa_t *wfa, coding_t *c)
+/*
+ *  Computes the inner products between the current state 'state1' and the
+ *  old states 0,...,'state1'-1
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	inner product tables 'c->ip_states_state' are computed.
+ */ 
+{
+   unsigned level;
+   unsigned state1, state2;
+
+   /*
+    *  Compute inner product <Phi_state1, Phi_state2>
+    */
+
+   for (level = c->options.images_level + 1;
+	level <= c->options.lc_max_level; level++)
+      for (state1 = from; state1 <= to; state1++)
+	 for (state2 = 0; state2 <= state1; state2++) 
+	    if (need_image (state2, wfa))
+	    {
+	       unsigned	label;
+	       real_t	ip = 0;
+	       
+	       for (label = 0; label < MAXLABELS; label++)
+	       {
+		  int	   domain1, domain2;
+		  unsigned edge1, edge2;
+		  real_t   sum, weight2;
+		  
+		  if (ischild (domain1 = wfa->tree [state1][label]))
+		  {
+		     sum = 0;
+		     if (ischild (domain2 = wfa->tree [state2][label]))
+			sum = get_ip_state_state (domain1, domain2,
+						  level - 1, c);
+		     
+		     for (edge2 = 0;
+			  isedge (domain2 = wfa->into [state2][label][edge2]);
+			  edge2++)
+		     {
+			weight2 = wfa->weight [state2][label][edge2];
+			sum += weight2 * get_ip_state_state (domain1, domain2,
+							     level - 1, c);
+		     }
+		     ip += sum;
+		  }
+		  for (edge1 = 0;
+		       isedge (domain1 = wfa->into [state1][label][edge1]);
+		       edge1++)
+		  {
+		     real_t weight1 = wfa->weight [state1][label][edge1];
+		     
+		     sum = 0;
+		     if (ischild (domain2 = wfa->tree [state2][label]))
+			sum = get_ip_state_state (domain1, domain2,
+						  level - 1, c);
+		     
+		     for (edge2 = 0;
+			  isedge (domain2 = wfa->into [state2][label][edge2]);
+			  edge2++)
+		     {
+			weight2 = wfa->weight [state2][label][edge2];
+			sum += weight2 * get_ip_state_state (domain1, domain2,
+							     level - 1, c);
+		     }
+		     ip += weight1 * sum;
+		  }
+	       }
+	       c->ip_states_state [state1][level][state2] = ip;
+	    }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static real_t 
+standard_ip_image_state (unsigned address, unsigned level, unsigned domain,
+			 const coding_t *c)
+/*
+ *  Returns the inner product between the subimage 'address' and the
+ *  state image 'domain' at given 'level'.  The stored state images
+ *  and the image tree are used to compute the inner product in the
+ *  standard way by multiplying the corresponding pixel values.
+ *
+ *  Return value:
+ *	computed inner product
+ */
+{
+   unsigned i;
+   real_t   ip = 0, *imageptr, *stateptr;
+
+   if (level > c->options.images_level)
+      error ("Level %d not supported.", level);
+   
+   imageptr = &c->pixels [address * size_of_level (level)];
+
+   stateptr = c->images_of_state [domain] + address_of_level (level);
+   
+   for (i = size_of_level (level); i; i--)
+      ip += *imageptr++ * *stateptr++;
+
+   return ip;
+}
+
+static real_t 
+standard_ip_state_state (unsigned domain1, unsigned domain2, unsigned level,
+			 const coding_t *c)
+/*
+ *  Returns the inner product between the subimage 'address' and the
+ *  state image 'state' at given 'level'.  The stored state images are
+ *  used to compute the inner product in the standard way by
+ *  multiplying the corresponding pixel values.
+ *
+ *  Return value:
+ *	computed inner product
+ */
+{
+   unsigned i;
+   real_t   ip = 0, *state1ptr, *state2ptr;
+
+   if (level > c->options.images_level)
+      error ("Level %d not supported.", level);
+
+   state1ptr = c->images_of_state [domain1] + address_of_level (level);
+   state2ptr = c->images_of_state [domain2] + address_of_level (level);
+   
+   for (i = size_of_level (level); i; i--)
+      ip += *state1ptr++ * *state2ptr++;
+
+   return ip;
+}
+
diff --git a/converter/other/fiasco/codec/ip.h b/converter/other/fiasco/codec/ip.h
new file mode 100644
index 00000000..e5e4dd65
--- /dev/null
+++ b/converter/other/fiasco/codec/ip.h
@@ -0,0 +1,37 @@
+/*
+ *  ip.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _IP_H
+#define _IP_H
+
+#include "cwfa.h"
+
+void 
+compute_ip_states_state (unsigned from, unsigned to,
+			 const wfa_t *wfa, coding_t *c);
+real_t 
+get_ip_state_state (unsigned domain1, unsigned domain2, unsigned level,
+		    const coding_t *c);
+void 
+compute_ip_images_state (unsigned image, unsigned address, unsigned level,
+			 unsigned n, unsigned from,
+			 const wfa_t *wfa, coding_t *c);
+real_t 
+get_ip_image_state (unsigned image, unsigned address, unsigned level,
+		    unsigned domain, const coding_t *c);
+
+#endif /* not _IP_H */
+
diff --git a/converter/other/fiasco/codec/motion.c b/converter/other/fiasco/codec/motion.c
new file mode 100644
index 00000000..92951281
--- /dev/null
+++ b/converter/other/fiasco/codec/motion.c
@@ -0,0 +1,338 @@
+/*
+ *  motion.c:		Motion compensation code	
+ *
+ *  Written by:		Ullrich Hafner
+ *			Michael Unger
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "image.h"
+#include "misc.h"
+#include "motion.h"
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+restore_mc (int enlarge_factor, image_t *image, const image_t *past,
+	    const image_t *future, const wfa_t *wfa)
+/*
+ *  Restore motion compensated prediction of 'image' represented by 'wfa'.
+ *  If 'enlarge_factor' != 0 then enlarge image by given amount.
+ *  Reference frames are given by 'past' and 'future'.
+ *
+ *  No return values.
+ */
+{
+   unsigned  state, label;
+   unsigned  root_state;
+   word_t   *mcblock1, *mcblock2;	/* MC blocks */
+
+#define FX(v) ((image->format == FORMAT_4_2_0) && band != Y ? ((v) / 2) : v)
+   
+   mcblock1 = Calloc (size_of_level (max ((int) wfa->wfainfo->p_max_level
+					  + 2 * enlarge_factor, 0)),
+		      sizeof (word_t));
+   mcblock2 = Calloc (size_of_level (max ((int) wfa->wfainfo->p_max_level
+					  + 2 * enlarge_factor, 0)),
+		      sizeof (word_t));
+
+   if (!image->color)
+      root_state = wfa->root_state;
+   else
+      root_state  = wfa->tree [wfa->tree [wfa->root_state][0]][0];
+   
+   for (state = wfa->basis_states; state <= root_state; state++)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (wfa->mv_tree[state][label].type != NONE)
+	 {
+	    color_e band;
+	    unsigned level  = wfa->level_of_state [state] - 1;
+	    unsigned width  = width_of_level (level);
+	    unsigned height = height_of_level (level);
+	    unsigned offset = image->width - width;
+	    
+	    switch (wfa->mv_tree [state][label].type)
+	    {
+	       case FORWARD:
+		  for (band  = first_band (image->color);
+		       band <= last_band (image->color); band++)
+		  {
+		     extract_mc_block (mcblock1, FX (width), FX (height),
+				       past->pixels [band], FX (past->width),
+				       wfa->wfainfo->half_pixel,
+				       FX (wfa->x [state][label]),
+				       FX (wfa->y [state][label]),
+				       FX (wfa->mv_tree [state][label].fx),
+				       FX (wfa->mv_tree [state][label].fy));
+		     {
+			word_t   *mc1;	/* current pixel in MC block */
+			word_t 	 *orig;	/* current pixel in original image */
+			unsigned  x, y;	/* pixel coordinates */
+			
+			mc1  = mcblock1;
+			orig = (word_t *) image->pixels [band]
+			       + FX (wfa->x[state][label])
+			       + FX (wfa->y[state][label]) * FX (image->width);
+		     
+			for (y = FX (height); y; y--)
+			{
+			   for (x = FX (width); x; x--)
+			      *orig++ += *mc1++;
+
+			   orig += FX (offset);
+			}
+		     }
+		  }
+		  break;
+	       case BACKWARD:
+		  for (band  = first_band (image->color);
+		       band <= last_band (image->color); band++)
+		  {
+		     extract_mc_block (mcblock1, FX (width), FX (height),
+				       future->pixels [band],
+				       FX (future->width),
+				       wfa->wfainfo->half_pixel,
+				       FX (wfa->x [state][label]),
+				       FX (wfa->y [state][label]),
+				       FX (wfa->mv_tree [state][label].bx),
+				       FX (wfa->mv_tree [state][label].by));
+		     {
+			word_t   *mc1;	/* current pixel in MC block 1 */
+			word_t   *orig;	/* current pixel in original image */
+			unsigned  x, y;	/* pixel coordinates */
+			
+			mc1  = mcblock1;
+			orig = (word_t *) image->pixels [band]
+			       + FX (wfa->x[state][label])
+			       + FX (wfa->y[state][label]) * FX (image->width);
+		     
+			for (y = FX (height); y; y--)
+			{
+			   for (x = FX (width); x; x--)
+			      *orig++ += *mc1++;
+
+			   orig += FX (offset);
+			}
+		     }
+		  }
+		  break;
+	       case INTERPOLATED:
+		  for (band  = first_band (image->color);
+		       band <= last_band (image->color); band++)
+		  {
+		     extract_mc_block (mcblock1, FX (width), FX (height),
+				       past->pixels [band], FX (past->width),
+				       wfa->wfainfo->half_pixel,
+				       FX (wfa->x[state][label]),
+				       FX (wfa->y[state][label]),
+				       FX (wfa->mv_tree[state][label].fx),
+				       FX (wfa->mv_tree[state][label].fy));
+		     extract_mc_block (mcblock2, FX (width), FX (height),
+				       future->pixels [band],
+				       FX (future->width),
+				       wfa->wfainfo->half_pixel,
+				       FX (wfa->x[state][label]),
+				       FX (wfa->y[state][label]),
+				       FX (wfa->mv_tree[state][label].bx),
+				       FX (wfa->mv_tree[state][label].by));
+		     {
+			word_t   *mc1;	/* current pixel in MC block 1 */
+			word_t   *mc2;	/* current pixel in MC block 1 */
+			word_t   *orig;	/* current pixel in original image */
+			unsigned  x, y;	/* pixel coordinates */
+			
+			mc1  = mcblock1;
+			mc2  = mcblock2;
+			orig = (word_t *) image->pixels [band]
+			       + FX (wfa->x[state][label])
+			       + FX (wfa->y[state][label]) * FX (image->width);
+			
+			for (y = FX (height); y; y--)
+			{
+			   for (x = FX (width); x; x--)
+#ifdef HAVE_SIGNED_SHIFT
+			      *orig++ += (*mc1++ + *mc2++) >> 1;
+#else /* not HAVE_SIGNED_SHIFT */
+			   *orig++ += (*mc1++ + *mc2++) / 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+			   orig += FX (offset);
+			}
+		     }
+		  }
+		  break;
+	       default:
+		  break;
+	    }
+	 }
+
+   if (image->color)
+   {
+      unsigned	  n;
+      word_t	 *ptr;
+      static int *clipping = NULL;
+      unsigned	  shift    = image->format == FORMAT_4_2_0 ? 2 : 0;
+
+      if (!clipping)			/* initialize clipping table */
+      {
+	 int i;
+	    
+	 clipping = Calloc (256 * 3, sizeof (int));
+	 for (i = -128; i < 128; i++)
+	    clipping [256 + i + 128] = i;
+	 for (i = 0; i < 256; i++)
+	    clipping [i] = clipping [256];
+	 for (i = 512; i < 512 + 256; i++)
+	    clipping [i] = clipping [511];
+	 clipping += 256 + 128;
+      }
+	 
+      ptr = image->pixels [Cb];
+      for (n = (image->width * image->height) >> shift; n; n--, ptr++)
+#ifdef HAVE_SIGNED_SHIFT
+	 *ptr = clipping [*ptr >> 4] << 4;
+#else /* not HAVE_SIGNED_SHIFT */
+	 *ptr = clipping [*ptr / 16] * 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+      ptr = image->pixels [Cr];
+      for (n = (image->width * image->height) >> shift; n; n--, ptr++)
+#ifdef HAVE_SIGNED_SHIFT
+	*ptr = clipping [*ptr >> 4] << 4;
+#else /* not HAVE_SIGNED_SHIFT */
+        *ptr = clipping [*ptr / 16] * 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+   }
+   
+   Free (mcblock1);
+   Free (mcblock2);
+}
+
+void
+extract_mc_block (word_t *mcblock, unsigned width, unsigned height,
+		  const word_t *reference, unsigned ref_width,
+		  bool_t half_pixel, unsigned xo, unsigned yo,
+		  unsigned mx, unsigned my)
+/*
+ *  Extract motion compensation image 'mcblock' of size 'width'x'height'
+ *  from 'reference' image (width is given by 'ref_width').
+ *  Coordinates of reference block are given by ('xo' + 'mx', 'yo' + 'my').
+ *  Use 'half_pixel' precision if specified.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'mcblock[]'	MCPE block is filled with reference pixels 
+ */
+{
+   if (!half_pixel)			/* Fullpixel precision */
+   {
+      const word_t *rblock;		/* pointer to reference image */
+      unsigned	    y;			/* current row */
+      
+      rblock  = reference + (yo + my) * ref_width + (xo + mx);
+      for (y = height; y; y--) 
+      {
+	 memcpy (mcblock, rblock, width * sizeof (word_t));
+
+	 mcblock += width;
+	 rblock  += ref_width;
+      }
+   }
+   else					/* Halfpixel precision */
+   {
+      unsigned	    x, y;		/* current coordinates */
+      unsigned	    offset;		/* remaining pixels in row */
+      const word_t *rblock;		/* pointer to reference image */
+      const word_t *ryblock;		/* pointer to next line */
+      const word_t *rxblock;		/* pointer to next column */
+      const word_t *rxyblock;		/* pointer to next column & row */
+   
+      rblock   = reference + (yo + my / 2) * ref_width + (xo + mx / 2);
+      ryblock  = rblock + ref_width;	/* pixel in next row */
+      rxblock  = rblock + 1;		/* pixel in next column */
+      rxyblock = ryblock + 1;		/* pixel in next row & column */
+      offset   = ref_width - width;
+      
+      if ((mx & 1) == 0)
+      {
+	 if ((my & 1) == 0)		/* Don't use halfpixel refinement */
+	    for (y = height; y; y--) 
+	    {
+	       memcpy (mcblock, rblock, width * sizeof (word_t));
+	       
+	       mcblock += width;
+	       rblock  += ref_width;
+	    }
+	 else				/* Halfpixel in y direction */
+	    for (y = height; y; y--) 
+	    {
+	       for (x = width; x; x--)
+#ifdef HAVE_SIGNED_SHIFT
+		  *mcblock++ = (*rblock++ + *ryblock++) >> 1;
+#else /* not HAVE_SIGNED_SHIFT */
+		  *mcblock++ = (*rblock++ + *ryblock++) / 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       rblock  += offset;
+	       ryblock += offset;
+	    }
+      }
+      else
+      {
+	 if ((my & 1) == 0)		/* Halfpixel in x direction */
+	    for (y = height; y; y--) 
+	    {
+	       for (x = width; x; x--)
+#ifdef HAVE_SIGNED_SHIFT
+		  *mcblock++ = (*rblock++ + *rxblock++) >> 1;
+#else /* not HAVE_SIGNED_SHIFT */
+		  *mcblock++ = (*rblock++ + *rxblock++) / 2;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       rblock  += offset;
+	       rxblock += offset;
+	    }
+	 else				/* Halfpixel in xy direction */
+	    for (y = height; y; y--) 
+	    {
+	       for (x = width; x; x--)
+#ifdef HAVE_SIGNED_SHIFT
+		  *mcblock++ = (*rblock++ + *rxblock++
+				+ *ryblock++ + *rxyblock++) >> 2;
+#else /* not HAVE_SIGNED_SHIFT */
+		  *mcblock++ = (*rblock++ + *rxblock++
+				+ *ryblock++ + *rxyblock++) / 4;
+#endif /* not HAVE_SIGNED_SHIFT */
+	       rblock   += offset;
+	       ryblock  += offset;
+	       rxblock  += offset;
+	       rxyblock += offset;
+	    }
+      }
+   }
+}
diff --git a/converter/other/fiasco/codec/motion.h b/converter/other/fiasco/codec/motion.h
new file mode 100644
index 00000000..2ea382f7
--- /dev/null
+++ b/converter/other/fiasco/codec/motion.h
@@ -0,0 +1,35 @@
+/*
+ *  motion.h
+ *
+ *  Written by:		Ullrich Hafner
+ *			Michael Unger
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MOTION_H
+#define _MOTION_H
+
+#include "wfa.h"
+#include "types.h"
+#include "image.h"
+
+void
+restore_mc (int enlarge_factor, image_t *image, const image_t *past,
+	    const image_t *future, const wfa_t *wfa);
+void
+extract_mc_block (word_t *mcblock, unsigned width, unsigned height,
+		  const word_t *reference, unsigned ref_width,
+		  bool_t half_pixel, unsigned xo, unsigned yo,
+		  unsigned mx, unsigned my);
+
+#endif /* not _MOTION_H */
+
diff --git a/converter/other/fiasco/codec/mwfa.c b/converter/other/fiasco/codec/mwfa.c
new file mode 100644
index 00000000..6f0af8be
--- /dev/null
+++ b/converter/other/fiasco/codec/mwfa.c
@@ -0,0 +1,864 @@
+/*
+ *  mwfa.c:		Initialization of MWFA coder
+ *
+ *  Written by:		Michael Unger
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include <ctype.h>
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "misc.h"
+#include "cwfa.h"
+#include "image.h"
+#include "mvcode.h"
+#include "motion.h"
+#include "mwfa.h"
+
+
+static const unsigned local_range = 6;
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+get_mcpe (word_t *mcpe, const image_t *original,
+	  unsigned x0, unsigned y0, unsigned width, unsigned height,
+	  const word_t *mcblock1, const word_t *mcblock2);
+static real_t
+mcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width,
+	   unsigned height, const word_t *mcblock1, const word_t *mcblock2);
+static real_t 
+find_best_mv (real_t price, const image_t *original, const image_t *reference,
+	      unsigned x0, unsigned y0, unsigned width, unsigned height,
+	      real_t *bits, int *mx, int *my, const real_t *mc_norms,
+	      const wfa_info_t *wi, const motion_t *mt);
+static real_t
+find_second_mv (real_t price, const image_t *original,
+		const image_t *reference, const word_t *mcblock1,
+		unsigned xr, unsigned yr, unsigned width, unsigned height,
+		real_t *bits, int *mx, int *my, const wfa_info_t *wi,
+		const motion_t *mt);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+motion_t *
+alloc_motion (const wfa_info_t *wi)
+/*
+ *  Motion structure constructor.
+ *  Allocate memory for the motion structure and
+ *  fill in default values specified by 'wi'.
+ *
+ *  Return value:
+ *	pointer to the new option structure or NULL on error
+ */
+{
+   int	     dx;			/* motion vector coordinate */
+   unsigned  level;
+   unsigned range_size = wi->half_pixel
+			 ? square (wi->search_range)
+			 : square (2 * wi->search_range);
+   motion_t *mt        = Calloc (1, sizeof (motion_t));
+   
+   mt->original = NULL;
+   mt->past     = NULL;
+   mt->future   = NULL;
+   mt->xbits 	= Calloc (2 * wi->search_range, sizeof (real_t));
+   mt->ybits 	= Calloc (2 * wi->search_range, sizeof (real_t));
+
+   for (dx = -wi->search_range; dx < (int) wi->search_range; dx++)
+   {
+      mt->xbits [dx + wi->search_range]
+	 = mt->ybits [dx + wi->search_range]
+	 = mv_code_table [dx + wi->search_range][1];
+   }
+   
+   mt->mc_forward_norms = Calloc (MAXLEVEL, sizeof (real_t *));
+   mt->mc_backward_norms = Calloc (MAXLEVEL, sizeof (real_t *));
+   
+   for (level = wi->p_min_level; level <= wi->p_max_level; level++)
+   {
+      mt->mc_forward_norms  [level] = Calloc (range_size, sizeof (real_t));
+      mt->mc_backward_norms [level] = Calloc (range_size, sizeof (real_t));
+   }
+
+   return mt;
+}
+
+void
+free_motion (motion_t *mt)
+/*
+ *  Motion struct destructor:
+ *  Free memory of 'motion' struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'motion' is discarded.
+ */
+{
+   unsigned level;
+
+   Free (mt->xbits);
+   Free (mt->ybits);
+   for (level = 0; level < MAXLEVEL; level++)
+   {
+      if (mt->mc_forward_norms [level])
+	 Free (mt->mc_forward_norms [level]);
+      if (mt->mc_backward_norms [level])
+	 Free (mt->mc_backward_norms [level]);
+   }
+   Free (mt->mc_forward_norms);
+   Free (mt->mc_backward_norms);
+   Free (mt);
+}
+
+void
+subtract_mc (image_t *image, const image_t *past, const image_t *future,
+	     const wfa_t *wfa)
+/*
+ *  Subtract motion compensation from chrom channels of 'image'.
+ *  Reference frames are given by 'past' and 'future'.
+ *
+ *  No return values.
+ */
+{
+   unsigned  state, label;
+   word_t   *mcblock1 = Calloc (size_of_level (wfa->wfainfo->p_max_level),
+				sizeof (word_t));
+   word_t   *mcblock2 = Calloc (size_of_level (wfa->wfainfo->p_max_level),
+				sizeof (word_t));
+
+   for (state = wfa->basis_states; state < wfa->states; state++)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (wfa->mv_tree [state][label].type != NONE)
+	 {
+	    color_e  band;		/* current color band */
+	    unsigned width, height;	/* size of mcblock */
+	    unsigned offset;		/* remaining pixels in original */
+	    
+	    width  = width_of_level (wfa->level_of_state [state] - 1);
+	    height = height_of_level (wfa->level_of_state [state] - 1);
+	    offset = image->width - width;
+	    
+	    switch (wfa->mv_tree [state][label].type)
+	    {
+	       case FORWARD:
+		  for (band  = first_band (image->color) + 1;
+		       band <= last_band (image->color); band++)
+		  {
+		     unsigned  y;	/* row of block */
+		     word_t   *mc1;	/* pixel in MC block 1 */
+		     word_t   *orig;	/* pixel in original image */
+		     
+		     extract_mc_block (mcblock1, width, height,
+				       past->pixels [band], past->width,
+				       wfa->wfainfo->half_pixel,
+				       wfa->x [state][label],
+				       wfa->y [state][label],
+				       (wfa->mv_tree [state][label].fx / 2)
+				       * 2,
+				       (wfa->mv_tree [state][label].fy / 2)
+				       * 2);
+		     mc1  = mcblock1;
+		     orig = image->pixels [band] + wfa->x [state][label]
+			    + wfa->y [state][label] * image->width;
+		     
+ 		     for (y = height; y; y--)
+		     {
+			unsigned x;	/* column of block */
+			
+			for (x = width; x; x--)
+			   *orig++ -= *mc1++;
+
+			orig += offset;
+		     }
+		  }
+		  break;
+	       case BACKWARD:
+		  for (band  = first_band (image->color) + 1;
+		       band <= last_band (image->color); band++)
+		  {
+		     unsigned  y;	/* row of block */
+		     word_t   *mc1;	/* pixel in MC block 1 */
+		     word_t   *orig;	/* pixel in original image */
+		     
+		     extract_mc_block (mcblock1, width, height,
+				       future->pixels [band], future->width,
+				       wfa->wfainfo->half_pixel,
+				       wfa->x [state][label],
+				       wfa->y [state][label],
+				       (wfa->mv_tree [state][label].bx / 2)
+				       * 2,
+				       (wfa->mv_tree [state][label].by / 2)
+				       * 2);
+		     mc1  = mcblock1;
+		     orig = image->pixels [band] + wfa->x [state][label]
+			    + wfa->y [state][label] * image->width;
+		     
+		     for (y = height; y; y--)
+		     {
+			unsigned x;	/* column of block */
+			
+			for (x = width; x; x--)
+			   *orig++ -= *mc1++;
+
+			orig += offset;
+		     }
+		  }
+		  break;
+	       case INTERPOLATED:
+		  for (band  = first_band (image->color) + 1;
+		       band <= last_band (image->color); band++)
+		  {
+		     unsigned  y;	/* row of block */
+		     word_t   *mc1;	/* pixel in MC block 1 */
+		     word_t   *mc2;	/* pixel in MC block 2 */
+		     word_t   *orig;	/* pixel in original image */
+		     
+		     extract_mc_block (mcblock1, width, height,
+				       past->pixels [band], past->width,
+				       wfa->wfainfo->half_pixel,
+				       wfa->x [state][label],
+				       wfa->y [state][label],
+				       (wfa->mv_tree[state][label].fx / 2)
+				       * 2,
+				       (wfa->mv_tree[state][label].fy / 2)
+				       * 2);
+		     extract_mc_block (mcblock2, width, height,
+				       future->pixels [band], future->width,
+				       wfa->wfainfo->half_pixel,
+				       wfa->x [state][label],
+				       wfa->y [state][label],
+				       (wfa->mv_tree[state][label].bx / 2)
+				       * 2,
+				       (wfa->mv_tree[state][label].by / 2)
+				       * 2);
+		     mc1  = mcblock1;
+		     mc2  = mcblock2;
+		     orig = image->pixels [band] + wfa->x [state][label]
+			    + wfa->y [state][label] * image->width;
+		     
+		     for (y = height; y; y--)
+		     {
+			unsigned x;	/* column of block */
+			
+			for (x = width; x; x--)
+			   *orig++ -= (*mc1++ + *mc2++) / 2;
+
+			orig += offset;
+		     }
+		  }
+		  break;
+	       default:
+		  break;
+	    }
+	 }
+
+   Free (mcblock1);
+   Free (mcblock2);
+}
+
+void
+find_P_frame_mc (word_t *mcpe, real_t price, range_t *range,
+		 const wfa_info_t *wi, const motion_t *mt)
+/*
+ *  Determine best motion vector for P-frame.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *            range->mvt_bits  (# of mv-tree bits)
+ *            range->mvxybits  (# of bits for vector components)
+ *            mt->mcpe         (MCPE in scan-order)
+ */
+{
+   unsigned  width   = width_of_level (range->level);
+   unsigned  height  = height_of_level (range->level);
+   word_t   *mcblock = Calloc (width * height, sizeof (word_t));
+   
+   range->mv_tree_bits = 1;
+   range->mv.type      = FORWARD;
+
+   /*
+    *  Find best matching forward prediction
+    */
+   find_best_mv (price, mt->original, mt->past, range->x, range->y,
+		 width, height, &range->mv_coord_bits, &range->mv.fx,
+		 &range->mv.fy, mt->mc_forward_norms [range->level], wi, mt);
+
+   /*
+    *  Compute MCPE
+    */
+   extract_mc_block (mcblock, width, height, mt->past->pixels [GRAY],
+		     mt->past->width, wi->half_pixel, range->x, range->y,
+		     range->mv.fx, range->mv.fy);
+   get_mcpe (mcpe, mt->original, range->x, range->y, width, height,
+	     mcblock, NULL);
+
+   Free (mcblock);
+}
+
+void
+find_B_frame_mc (word_t *mcpe, real_t price, range_t *range,
+		 const wfa_info_t *wi, const motion_t *mt)
+/*
+ *  Determines best motion compensation for B-frame.
+ *  Steps:
+ *         1)  find best forward motion vector
+ *         2)  find best backward motion vector
+ *         3)  try both motion vectors together (interpolation)
+ *         4)  choose best mode (FORWARD, BACKWARD or INTERPOLATED)
+ *  Bitcodes:
+ *    FORWARD      000
+ *    BACKWARD     001
+ *    INTERPOLATED  01
+ *  
+ *  Return values:
+ *            range->mvt_bits  (# of mv-tree bits)
+ *            range->mvxybits  (# of bits for vector components)
+ *            mt->mcpe         (MCPE in scan-order)
+ */
+{
+   mc_type_e  mctype;			/* type of motion compensation */
+   real_t     forward_costs;		/* costs of FORWARD mc */
+   real_t     backward_costs;		/* costs of BACKWARD mc */
+   real_t     interp_costs;		/* costs of INTERPOLATED mc */
+   real_t     forward_bits;		/* bits for FORWARD mc */
+   real_t     backward_bits;		/* bits for BACKWARD mc */
+   real_t     interp_bits;		/* bits for INTERPOLATED mc */
+   int	      fx,  fy;			/* coordinates FORWARD mc */
+   int	      bx,  by;			/* coordinates BACKWARD mc */
+   int	      ifx, ify;			/* coordinates forw. INTERPOLATED mc */
+   int	      ibx, iby;			/* coordinates back. INTERPOLATED mc */
+   unsigned   width    = width_of_level (range->level);
+   unsigned   height   = height_of_level (range->level);
+   word_t    *mcblock1 = Calloc (width * height, sizeof (word_t));
+   word_t    *mcblock2 = Calloc (width * height, sizeof (word_t));
+   
+   /*
+    *  Forward interpolation: use past frame as reference
+    */
+   forward_costs = find_best_mv (price, mt->original, mt->past,
+				 range->x, range->y, width, height,
+				 &forward_bits, &fx, &fy,
+				 mt->mc_forward_norms [range->level], wi, mt)
+		   + 3 * price; /* code 000 */
+
+   /*
+    *  Backward interpolation: use future frame as reference
+    */
+   backward_costs = find_best_mv (price, mt->original, mt->future,
+				  range->x, range->y, width, height,
+				  &backward_bits, &bx, &by,
+				  mt->mc_backward_norms [range->level], wi, mt)
+		    + 3 * price; /* code 001 */
+
+   /*
+    *  Bidirectional interpolation: use both past and future frame as reference
+    */
+   if (wi->cross_B_search) 
+   {
+      real_t icosts1;			/* costs interpolation alternative 1 */
+      real_t icosts2;			/* costs interpolation alternative 2 */
+      real_t ibackward_bits;		/* additional bits alternative 1 */
+      real_t iforward_bits;		/* additional bits alternative 1 */
+      
+      /*
+       *  Alternative 1: keep forward mv and vary backward mv locally
+       */
+      extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],
+			mt->past->width, wi->half_pixel,
+			range->x, range->y, fx, fy);
+
+      ibx = bx;				/* start with backward coordinates */
+      iby = by;
+      icosts1 = find_second_mv (price, mt->original, mt->future,
+				mcblock1, range->x, range->y, width, height,
+				&ibackward_bits, &ibx, &iby, wi, mt)
+		+ (forward_bits + 2) * price; /* code 01 */
+
+      /*
+       *  Alternative 2: Keep backward mv and vary forward mv locally
+       */
+      extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY],
+			mt->future->width, wi->half_pixel,
+			range->x, range->y, bx, by);
+
+      ifx = fx;
+      ify = fy;
+      icosts2 = find_second_mv (price, mt->original, mt->past,
+				mcblock1, range->x, range->y, width, height,
+				&iforward_bits, &ifx, &ify, wi, mt)
+		+ (backward_bits + 2) * price; /* code 01 */
+      
+      /*
+       *  Choose best alternative
+       */
+      if (icosts1 < icosts2)
+      {
+	 ifx 	      = fx;
+	 ify 	      = fy;
+	 interp_bits  = forward_bits + ibackward_bits;
+	 interp_costs = icosts1;
+      }
+      else
+      {
+	 ibx 	      = bx;
+	 iby 	      = by;
+	 interp_bits  = iforward_bits + backward_bits;
+	 interp_costs = icosts2;
+      }
+   }
+   else					/* local exhaustive search */
+   {
+      /*
+       *  Keep forward and backward mv due to time constraints
+       */
+
+      ifx = fx;
+      ify = fy;
+      ibx = bx;
+      iby = by;
+      interp_bits = forward_bits + backward_bits;
+
+      extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],
+			mt->past->width, wi->half_pixel,
+			range->x, range->y, fx, fy);
+      extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY],
+			mt->future->width, wi->half_pixel,
+			range->x, range->y, bx, by);
+      interp_costs = mcpe_norm (mt->original, range->x, range->y,
+				width, height, mcblock1, mcblock2)
+		     + (interp_bits + 2) * price; /* code 01 */
+   }
+
+   /*
+    *  Choose alternative with smallest costs
+    */
+   if (forward_costs <= interp_costs)
+   {
+      if (forward_costs <= backward_costs)
+	 mctype = FORWARD;
+      else
+	 mctype = BACKWARD;
+   }
+   else
+   {
+      if (backward_costs <= interp_costs)
+	 mctype = BACKWARD;
+      else
+	 mctype = INTERPOLATED;
+   }
+
+   switch (mctype)
+   {
+      case FORWARD:
+	 range->mv_tree_bits  = 3;
+	 range->mv_coord_bits = forward_bits;
+	 range->mv.type       = FORWARD;
+	 range->mv.fx         = fx;
+	 range->mv.fy         = fy;
+	 extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],
+			   mt->past->width, wi->half_pixel,
+			   range->x, range->y, range->mv.fx, range->mv.fy);
+	 get_mcpe (mcpe, mt->original, range->x, range->y, width, height,
+		   mcblock1, NULL);
+	 break;
+      case BACKWARD:
+	 range->mv_tree_bits  = 3;
+	 range->mv_coord_bits = backward_bits;
+	 range->mv.type       = BACKWARD;
+	 range->mv.bx         = bx;
+	 range->mv.by         = by;
+	 extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY],
+			   mt->future->width, wi->half_pixel,
+			   range->x, range->y, range->mv.bx, range->mv.by);
+	 get_mcpe (mcpe, mt->original, range->x, range->y, width, height,
+		   mcblock1, NULL);
+	 break;
+      case INTERPOLATED:
+	 range->mv_tree_bits  = 2;
+	 range->mv_coord_bits = interp_bits;
+	 range->mv.type       = INTERPOLATED;
+	 range->mv.fx         = ifx;
+	 range->mv.fy         = ify;
+	 range->mv.bx         = ibx;
+	 range->mv.by         = iby;
+	 extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],
+			   mt->past->width, wi->half_pixel,
+			   range->x, range->y, range->mv.fx, range->mv.fy);
+	 extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY],
+			   mt->future->width, wi->half_pixel,
+			   range->x, range->y, range->mv.bx, range->mv.by);
+	 get_mcpe (mcpe, mt->original, range->x, range->y, width, height,
+		   mcblock1, mcblock2);
+	 break;
+      default:
+	 break;
+   }
+
+   Free (mcblock1);
+   Free (mcblock2);
+}
+
+void
+fill_norms_table (unsigned x0, unsigned y0, unsigned level,
+		  const wfa_info_t *wi, motion_t *mt)
+/*
+ *  Compute norms of difference images for all possible displacements
+ *  in 'mc_forward_norm' and 'mc_backward_norm'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'mt->mc_backward_norms' are computed
+ *	'mt->mc_forward_norms' are computed 
+ */
+{
+   int	     mx, my;			/* coordinates of motion vector */
+   unsigned  sr;			/* mv search range +-'sr' pixels */
+   unsigned  index   = 0;		/* index of motion vector */
+   unsigned  width   = width_of_level (level);
+   unsigned  height  = height_of_level (level);
+   word_t   *mcblock = Calloc (width * height, sizeof (word_t));
+
+   sr = wi->half_pixel ? wi->search_range / 2 :  wi->search_range;
+   
+   for (my = -sr; my < (int) sr; my++)
+      for (mx = -sr; mx < (int) sr; mx++, index++)
+      {
+	  if ((int) x0 + mx < 0 ||	/* block outside visible area */
+	      x0 + mx + width > mt->original->width || 
+	      (int) y0 + my < 0 ||
+	      y0 + my + height > mt->original->height)
+	  {
+	     mt->mc_forward_norms [level][index]  = 0.0;
+	     mt->mc_backward_norms [level][index] = 0.0;
+	  }
+	  else
+	  {
+	     extract_mc_block (mcblock, width, height, mt->past->pixels [GRAY],
+			       mt->past->width, wi->half_pixel,
+			       x0, y0, mx, my);
+	     mt->mc_forward_norms [level][index]
+		= mcpe_norm (mt->original, x0, y0, width, height,
+			     mcblock, NULL);
+
+	     if (mt->frame_type == B_FRAME)
+	     {
+		extract_mc_block (mcblock, width, height,
+				  mt->future->pixels [GRAY],
+				  mt->future->width, wi->half_pixel,
+				  x0, y0, mx, my);
+		mt->mc_backward_norms[level][index]
+		   = mcpe_norm (mt->original, x0, y0, width, height,
+				mcblock, NULL); 
+	     }
+	  }
+       }
+
+   Free (mcblock);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+get_mcpe (word_t *mcpe, const image_t *original, unsigned x0, unsigned y0,
+	  unsigned width, unsigned height, const word_t *mcblock1,
+	  const word_t *mcblock2)
+/*
+ *  Compute MCPE image 'original' - reference. The reference is either
+ *  composed of 'mcblock1' or of ('mcblock1' + 'mcblock2') / 2 (if
+ *  'mcblock2' != NULL).  Coordinates of original block are given by
+ *  'x0', 'y0', 'width', and 'height'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'mcpe []' is filled with the delta image
+ */
+{
+   const word_t	*oblock;		/* pointer to original image */
+
+   assert (mcpe);
+   
+   oblock = original->pixels [GRAY] + y0 * original->width + x0;
+
+   if (mcblock2 != NULL)		/* interpolated prediction */
+   {
+      unsigned x, y;			/* current coordinates */
+      
+      for (y = height; y; y--) 
+      {
+	 for (x = width; x; x--)
+	    *mcpe++ = *oblock++ - (*mcblock1++ + *mcblock2++) / 2;
+
+	 oblock += original->width - width;
+      }
+   }
+   else					/* forward or backward prediction */
+   {
+      unsigned x, y;			/* current coordinates */
+      
+      for (y = height; y; y--) 
+      {
+	 for (x = width; x; x--)
+	    *mcpe++ = *oblock++ - *mcblock1++;
+      
+	 oblock += original->width - width;
+      }
+   }
+}
+
+static real_t
+mcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width,
+	   unsigned height, const word_t *mcblock1, const word_t *mcblock2)
+/*
+ *  Compute norm of motion compensation prediction error.
+ *  Coordinates of 'original' block are given by ('x0', 'y0')
+ *  and 'width', 'height'.
+ *  Reference blocks are stored in 'mcimage1' and 'mcimage2'.
+ *
+ *  Return value:
+ *	square of norm of difference image
+ */
+{
+   unsigned  n;
+   real_t    norm = 0;
+   word_t   *mcpe = Calloc (width * height, sizeof (word_t));
+   word_t   *ptr  = mcpe;
+   
+   get_mcpe (mcpe, original, x0, y0, width, height, mcblock1, mcblock2);
+
+   for (n = height * width; n; n--, ptr++) 
+      norm += square (*ptr / 16);
+   
+   Free (mcpe);
+   
+   return norm;
+}
+
+static real_t 
+find_best_mv (real_t price, const image_t *original, const image_t *reference,
+	      unsigned x0, unsigned y0, unsigned width, unsigned height,
+	      real_t *bits, int *mx, int *my, const real_t *mc_norms,
+	      const wfa_info_t *wi, const motion_t *mt)
+/*
+ *  Find best matching motion vector in image 'reference' to predict
+ *  the block ('x0', 'y0') of size 'width'x'height in image 'original'.
+ *
+ *  Return values:
+ *	prediction costs
+ *
+ *  Side effects:
+ *	'mx', 'my'		coordinates of motion vector
+ *	'bits'			number of bits to encode mv
+ */
+{
+   unsigned sr;				/* mv search range +/- 'sr' pixels */
+   unsigned index;			/* index of motion vector */
+   int 	    x, y;			/* coordinates of motion vector */
+   real_t   costs;			/* costs arising if mv is chosen */
+   real_t   mincosts = MAXCOSTS;	/* best costs so far  */
+   unsigned bitshift;			/* half_pixel coordinates multiplier */
+   
+   *mx = *my = 0;
+
+   /*
+    *  Find best fitting motion vector:
+    *  Use exhaustive search in the interval x,y +- sr (no halfpixel accuracy)
+    *					  or x,y +- sr/2  (halfpixel accuracy)
+    */
+   sr 	    = wi->half_pixel ? wi->search_range / 2 :  wi->search_range;
+   bitshift = (wi->half_pixel ? 2 : 1);	/* bit0 reserved for halfpixel pred. */
+   
+   for (index = 0, y = -sr; y < (int) sr; y++)
+      for (x = -sr; x < (int) sr; x++, index++)
+	 if ((int) x0 + x >= 0 && (int) y0 + y >= 0 &&	
+	     x0 + x + width  <= original->width && 
+	     y0 + y + height <= original->height)
+	 {
+	    /*
+	     *  Block is inside visible area.
+	     *  Compare current costs with 'mincosts'
+	     */
+	    costs = mc_norms [index]
+		    + (mt->xbits [(x + sr) * bitshift]
+		       + mt->ybits [(y + sr) * bitshift]) * price;
+
+	     if (costs < mincosts)
+	     {
+		mincosts = costs;
+		*mx      = x * bitshift;
+		*my      = y * bitshift;
+	     }
+	 }
+
+   /*
+    *  Halfpixel prediction:
+    *  Compare all nine combinations (-1, y), (0, y), (+1, y) for y = -1,0,+1
+    */
+   if (wi->half_pixel)
+   {
+      int	rx, ry;			/* halfpixel refinement */
+      unsigned	bestrx, bestry;		/* coordinates of best mv */
+      word_t   *mcblock = Calloc (width * height, sizeof (word_t));
+      
+      bestrx = bestry = 0;
+      for (rx = -1; rx <= 1; rx++)
+	 for (ry = -1; ry <= 1; ry++)
+	 {
+	    /*
+	     *  Check if the new motion vector is in allowed area
+	     */
+	    if (rx == 0 && ry == 0)	/* already tested */
+	       continue;
+	    if ((int) x0 + (*mx / 2) + rx < 0 || /* outside visible area */
+		x0 + (*mx / 2) + rx + width > original->width ||
+		(int) y0 + (*my / 2) + ry < 0 || 
+		y0 + (*my / 2) + ry + height > original->height)
+	       continue;
+	    if (*mx + rx < (int) -sr || *mx + rx >= (int) sr ||
+		*my + ry < (int) -sr || *my + ry >= (int) sr) 
+	       continue;		/* out of bounds */
+
+	    /*
+	     *  Compute costs of new motion compensation
+	     */
+	    extract_mc_block (mcblock, width, height,
+			      reference->pixels [GRAY],
+			      reference->width, wi->half_pixel,
+			      x0, y0, *mx + rx, *my + ry);
+	    costs = mcpe_norm (mt->original, x0, y0, width, height, mcblock,
+			       NULL)
+		    + (mt->xbits [*mx + rx + sr * bitshift]
+		       + mt->ybits [*my + ry + sr * bitshift]) * price;
+	    if (costs < mincosts)
+	    {
+	       bestrx   = rx;
+	       bestry   = ry;
+	       mincosts = costs;
+	    }
+	 }
+
+      *mx += bestrx;
+      *my += bestry;
+
+      Free (mcblock);
+   } /* halfpixel */
+	     
+   *bits = mt->xbits [*mx + sr * bitshift] + mt->ybits [*my + sr * bitshift];
+
+   return mincosts;
+}
+
+static real_t
+find_second_mv (real_t price, const image_t *original,
+		const image_t *reference, const word_t *mcblock1,
+		unsigned xr, unsigned yr, unsigned width, unsigned height,
+		real_t *bits, int *mx, int *my, const wfa_info_t *wi,
+		const motion_t *mt)
+/*
+ *  Search local area (*mx,*my) for best additional mv.
+ *  Overwrite mt->tmpblock.
+ *  TODO check sr = search_range
+ *
+ *  Return values:
+ *	prediction costs
+ *
+ *  Side effects:
+ *	'mx','my'	coordinates of mv
+ *      'bits'		number of bits to encode mv
+ */
+{
+   real_t    mincosts = MAXCOSTS;	/* best costs so far  */
+   unsigned  sr;			/* MV search range +/- 'sr' pixels */
+   int       x, y;			/* coordinates of motion vector */
+   int       y0, y1, x0, x1;		/* start/end coord. of search range */
+   unsigned  bitshift;			/* half_pixel coordinates multiplier */
+   word_t   *mcblock2 = Calloc (width * height, sizeof (word_t));
+
+   sr = wi->search_range;
+
+   y0 = max ((int) -sr, *my - (int) local_range);
+   y1 = min ((int) sr, *my + (int) local_range);
+   x0 = max ((int) -sr, *mx - (int) local_range);
+   x1 = min ((int) sr, *mx + (int) local_range);
+
+   *mx = *my = 0;
+
+   bitshift = (wi->half_pixel ? 2 : 1);	/* bit0 reserved for halfpixel pred. */
+
+   
+   for (y = y0; y < y1; y++)
+      for (x = x0; x < x1; x++)
+      {
+	 real_t costs;			/* costs arising if mv is chosen */
+	 
+	 /*
+	  *  Test each mv ('x', 'y') in the given search range:
+	  *  Get the new motion compensation image from 'reference' and compute
+	  *  the norm of the motion compensation prediction error
+	  *  'original' - 0.5 * ('firstmc' + 'reference')
+	  */
+	 if ((int) (xr * bitshift) + x < 0 ||	/* outside visible area */
+	     xr * bitshift + x > (original->width - width) * bitshift ||
+	     (int) (yr * bitshift) + y < 0 ||
+	     yr * bitshift + y > (original->height - height) * bitshift)
+	    continue;
+	 
+	 extract_mc_block (mcblock2, width, height,
+			   reference->pixels [GRAY], reference->width,
+			   wi->half_pixel, x0, y0, x, y);
+
+	 costs  = mcpe_norm (mt->original, x0, y0, width, height,
+			     mcblock1, mcblock2)
+		  + (mt->xbits [x + sr] + mt->ybits [y + sr]) * price;
+	 
+	 if (costs < mincosts)
+	 {
+	    mincosts = costs;
+	    *mx      = x;
+	    *my      = y;
+	 }
+      }
+
+   *bits = mt->xbits [*mx + sr] + mt->ybits [*my + sr];
+
+   Free (mcblock2);
+
+   return mincosts;
+}
diff --git a/converter/other/fiasco/codec/mwfa.h b/converter/other/fiasco/codec/mwfa.h
new file mode 100644
index 00000000..52f41866
--- /dev/null
+++ b/converter/other/fiasco/codec/mwfa.h
@@ -0,0 +1,44 @@
+/*
+ *  mwfa.h
+ *
+ *  Written by:		Michael Unger
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MWFA_H
+#define _MWFA_H
+
+#include "types.h"
+#include "image.h"
+#include "wfa.h"
+#include "cwfa.h"
+
+void
+fill_norms_table (unsigned x0, unsigned y0, unsigned level,
+		  const wfa_info_t *wi, motion_t *mt);
+void
+find_B_frame_mc (word_t *mcpe, real_t price, range_t *range,
+		 const wfa_info_t *wi, const motion_t *mt);
+void
+find_P_frame_mc (word_t *mcpe, real_t price, range_t *range,
+		 const wfa_info_t *wi, const motion_t *mt);
+void
+subtract_mc (image_t *image, const image_t *past, const image_t *future,
+	     const wfa_t *wfa);
+void
+free_motion (motion_t *mt);
+motion_t *
+alloc_motion (const wfa_info_t *wi);
+
+#endif /* not _MWFA_H */
+
diff --git a/converter/other/fiasco/codec/options.c b/converter/other/fiasco/codec/options.c
new file mode 100644
index 00000000..77dbaf00
--- /dev/null
+++ b/converter/other/fiasco/codec/options.c
@@ -0,0 +1,894 @@
+/*
+ *  options.c:		FIASCO options handling
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/10/28 17:39:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.5 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+
+#include <string.h>
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include <stdio.h>
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "misc.h"
+#include "bit-io.h"
+#include "fiasco.h"
+#include "options.h"
+
+fiasco_c_options_t *
+fiasco_c_options_new (void)
+/*
+ *  FIASCO options constructor.
+ *  Allocate memory for the FIASCO coder options structure and
+ *  fill in default values.
+ *
+ *  Return value:
+ *	pointer to the new option structure
+ */
+{
+   c_options_t 	      *options = calloc (1, sizeof (c_options_t));
+   fiasco_c_options_t *public  = calloc (1, sizeof (fiasco_c_options_t));
+
+   if (!options || !public)
+   {
+      set_error (_("Out of memory."));
+      return NULL;
+   }
+   public->private 	      = options;
+   public->delete 	      = fiasco_c_options_delete;
+   public->set_tiling 	      = fiasco_c_options_set_tiling;
+   public->set_frame_pattern  = fiasco_c_options_set_frame_pattern;
+   public->set_basisfile      = fiasco_c_options_set_basisfile;
+   public->set_chroma_quality = fiasco_c_options_set_chroma_quality;
+   public->set_optimizations  = fiasco_c_options_set_optimizations;
+   public->set_video_param    = fiasco_c_options_set_video_param;
+   public->set_quantization   = fiasco_c_options_set_quantization;
+   public->set_progress_meter = fiasco_c_options_set_progress_meter;
+   public->set_smoothing      = fiasco_c_options_set_smoothing;
+   public->set_title   	      = fiasco_c_options_set_title;
+   public->set_comment        = fiasco_c_options_set_comment;
+   
+   strcpy (options->id, "COFIASCO");
+
+   /*
+    *  Set default value of fiasco options
+    */
+   options->basis_name 		  = strdup ("small.fco");
+   options->lc_min_level 	  = 4;
+   options->lc_max_level 	  = 12;
+   options->p_min_level 	  = 8;
+   options->p_max_level 	  = 10;
+   options->images_level 	  = 5;
+   options->max_states 		  = MAXSTATES;
+   options->chroma_max_states 	  = 40;
+   options->max_elements 	  = MAXEDGES;
+   options->tiling_exponent 	  = 4;
+   options->tiling_method 	  = FIASCO_TILING_VARIANCE_DSC;
+   options->id_domain_pool 	  = strdup ("rle");
+   options->id_d_domain_pool 	  = strdup ("rle");
+   options->id_rpf_model 	  = strdup ("adaptive");
+   options->id_d_rpf_model 	  = strdup ("adaptive");
+   options->rpf_mantissa 	  = 3;
+   options->rpf_range 		  = FIASCO_RPF_RANGE_1_50;
+   options->dc_rpf_mantissa 	  = 5;
+   options->dc_rpf_range 	  = FIASCO_RPF_RANGE_1_00;
+   options->d_rpf_mantissa 	  = 3;
+   options->d_rpf_range 	  = FIASCO_RPF_RANGE_1_50;
+   options->d_dc_rpf_mantissa 	  = 5;
+   options->d_dc_rpf_range 	  = FIASCO_RPF_RANGE_1_00;
+   options->chroma_decrease 	  = 2.0;
+   options->prediction 		  = NO;
+   options->delta_domains 	  = YES;
+   options->normal_domains 	  = YES;
+   options->search_range 	  = 16;
+   options->fps 		  = 25;
+   options->pattern 		  = strdup ("IPPPPPPPPP");
+   options->reference_filename 	  = NULL;
+   options->half_pixel_prediction = NO;
+   options->cross_B_search 	  = YES;
+   options->B_as_past_ref 	  = YES;
+   options->check_for_underflow   = NO;
+   options->check_for_overflow 	  = NO;
+   options->second_domain_block   = NO;
+   options->full_search 	  = NO;
+   options->progress_meter 	  = FIASCO_PROGRESS_NONE;
+   options->smoothing 	 	  = 70;
+   options->comment 		  = strdup ("");
+   options->title 		  = strdup ("");
+   
+   return public;
+}
+
+void
+fiasco_c_options_delete (fiasco_c_options_t *options)
+/*
+ *  FIASCO options destructor.
+ *  Free memory of FIASCO options struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'options' is discarded.
+ */
+{
+   c_options_t *this = cast_c_options (options);
+
+   if (!this)
+      return;
+   
+   Free (this->id_domain_pool);
+   Free (this->id_d_domain_pool);
+   Free (this->id_rpf_model);
+   Free (this->id_d_rpf_model);
+   Free (this->pattern);
+   Free (this->comment);
+   Free (this->title);
+   
+   Free (this);
+
+   return;
+}
+
+int
+fiasco_c_options_set_tiling (fiasco_c_options_t *options,
+			     fiasco_tiling_e method, unsigned exponent)
+/*
+ *  Set tiling `method' and `exponent'.
+ *  See type `fiasco_tiling_e' for a list of valid  tiling `methods'.
+ *  The image is subdivied into 2^`exponent' tiles
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   switch (method)
+   {
+      case FIASCO_TILING_SPIRAL_ASC:
+      case FIASCO_TILING_SPIRAL_DSC:
+      case FIASCO_TILING_VARIANCE_ASC:
+      case FIASCO_TILING_VARIANCE_DSC:
+	 this->tiling_method = method;
+	 break;
+      default:
+	 set_error (_("Invalid tiling method `%d' specified "
+		      "(valid methods are 0, 1, 2, or 3)."), method);
+	 return 0;
+   }
+   this->tiling_exponent = exponent;
+   
+   return 1;
+}
+
+int
+fiasco_c_options_set_frame_pattern (fiasco_c_options_t *options,
+				    const char *pattern)
+/*
+ *  Set `pattern' of input frames.
+ *  `pattern' has to be a sequence of the following
+ *  characters (case insensitive):
+ *  'i' intra frame
+ *  'p' predicted frame
+ *  'b' bidirectional predicted frame
+ *  E.g. pattern = 'IBBPBBPBB'
+ *
+ *  When coding video frames the prediction type of input frame N is determined
+ *  by reading `pattern' [N] (`pattern' is periodically extended).
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (!pattern)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "pattern");
+      return 0;
+   }
+   else if (strlen (pattern) < 1)
+   {
+      set_error (_("Frame type pattern doesn't contain any character."));
+      return 0;
+   }
+   else
+   {
+      const char *str;
+      bool_t 	  parse_error = NO;
+      int	  c 	      = 0;
+      
+      for (str = pattern; *str && !parse_error; str++)
+	 switch (*str)
+	 {
+	    case 'i':
+	    case 'I':
+	    case 'b':
+	    case 'B':
+	    case 'p':
+	    case 'P':
+	       break;
+	    default:
+	       c = *str;
+	       parse_error = YES;
+	 }
+
+      if (parse_error)
+      {
+	 set_error (_("Frame type pattern contains invalid character `%c' "
+		      "(choose I, B or P)."), c);
+	 return 0;
+      }
+      else
+      {
+	 Free (this->pattern);
+	 this->pattern = strdup (pattern);
+
+	 return 1;
+      }
+   }
+}
+
+int
+fiasco_c_options_set_basisfile (fiasco_c_options_t *options,
+				const char *filename)
+/*
+ *  Set `filename' of FIASCO initial basis.
+ *  
+ *  Return value:
+ *	1 on success (if the file is readable)
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (!filename)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "filename");
+      return 0;
+   }
+   else
+   {
+       /* Skip this because basis file may be linked with program, not
+          in a separate file.  See get_linked_basis().  NETPBM
+      FILE *file = open_file (filename, "FIASCO_DATA", READ_ACCESS);
+      if (file)
+      {
+	 fclose (file);
+	 return 1;
+      }
+      else
+      {
+	 set_error (_("Can't read basis file `%s'.\n%s."), filename,
+		    get_system_error ());
+	 return 0;
+      }
+      */ return 1;
+   }
+}
+
+int
+fiasco_c_options_set_chroma_quality (fiasco_c_options_t *options,
+				     float quality_factor,
+				     unsigned dictionary_size)
+/*
+ *  Set color compression parameters.
+ *  When coding chroma channels (Cb and Cr)
+ *  - approximation quality is given by `quality_factor' * `Y quality' and
+ *  - `dictionary_size' gives the number of dictionary elements.
+ *  
+ *  If 'quality' <= 0 then the luminancy coding quality is also during
+ *  chroma channel coding.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (!dictionary_size)
+   {
+      set_error (_("Size of chroma compression dictionary has to be "
+		   "a positive number."));
+      return 0;
+   }
+   else if (quality_factor <= 0)
+   {
+      set_error (_("Quality of chroma channel compression has to be "
+		   "positive value."));
+      return 0;
+   }
+   else
+   {
+      this->chroma_decrease   = quality_factor;
+      this->chroma_max_states = dictionary_size;
+
+      return 1;
+   }
+}
+
+int
+fiasco_c_options_set_optimizations (fiasco_c_options_t *options,
+				    unsigned min_block_level,
+				    unsigned max_block_level,
+				    unsigned max_elements,
+				    unsigned dictionary_size,
+				    unsigned optimization_level)
+/*
+ *  Set various optimization parameters.
+ *  - During compression only image blocks of size
+ *    {`min_block_level', ... ,`max_block_level'} are considered.
+ *    The smaller this set of blocks is the faster the coder runs
+ *    and the worse the image quality will be.  
+ *  - An individual approximation may use at most `max_elements'
+ *    elements of the dictionary which itself contains at most
+ *    `dictionary_size' elements. The smaller these values are
+ *    the faster the coder runs and the worse the image quality will be. 
+ *  - `optimization_level' enables some additional low level optimizations.
+ *    0: standard approximation method
+ *    1: significantly increases the approximation quality,
+ *       running time is twice as high as with the standard method
+ *    2: hardly increases the approximation quality of method 1, 
+ *       running time is twice as high as with method 1
+ *       (this method just remains for completeness)
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (!dictionary_size)
+   {
+      set_error (_("Size of dictionary has to be a positive number."));
+      return 0;
+   }
+   else if (!max_elements)
+   {
+      set_error (_("At least one dictionary element has to be used "
+		   "in an approximation."));
+      return 0;
+   }
+   else if (max_block_level < 4)
+   {
+      set_error (_("Maximum image block size has to be at least level 4."));
+      return 0;
+   }
+   else if (min_block_level < 4)
+   {
+      set_error (_("Minimum image block size has to be at least level 4."));
+      return 0;
+   }
+   else if (max_block_level < min_block_level)
+   {
+      set_error (_("Maximum block size has to be larger or "
+		   "equal minimum block size."));
+      return 0;
+   }
+   else
+   {
+      this->lc_min_level 	= min_block_level;
+      this->lc_max_level 	= max_block_level;
+      this->max_states 	 	= dictionary_size;
+      this->max_elements 	= max_elements;
+      this->second_domain_block = optimization_level > 0 ? YES : NO;
+      this->check_for_overflow  = optimization_level > 1 ? YES : NO;
+      this->check_for_underflow = optimization_level > 1 ? YES : NO;
+      this->full_search 	= optimization_level > 1 ? YES : NO;
+
+      return 1;
+   }
+}
+
+int
+fiasco_c_options_set_prediction (fiasco_c_options_t *options,
+				 int intra_prediction,
+				 unsigned min_block_level,
+				 unsigned max_block_level)
+/*
+ *  Set minimum and maximum size of image block prediction to
+ *  `min_block_level' and `max_block_level'.
+ *  (For either motion compensated prediction of inter frames
+ *   or DC based prediction of intra frames)
+ *  Prediction of intra frames is only used if `intra_prediction' != 0.
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (max_block_level < 6)
+   {
+      set_error (_("Maximum prediction block size has to be "
+		   "at least level 6"));
+      return 0;
+   }
+   else if (min_block_level < 6)
+   {
+      set_error (_("Minimum prediction block size has to be "
+		   "at least level 6"));
+      return 0;
+   }
+   else if (max_block_level < min_block_level)
+   {
+      set_error (_("Maximum prediction block size has to be larger or "
+		   "equal minimum block size."));
+      return 0;
+   }
+   else
+   {
+      this->p_min_level = min_block_level;
+      this->p_max_level = max_block_level;
+      this->prediction  = intra_prediction;
+      
+      return 1;
+   }
+}
+
+int
+fiasco_c_options_set_video_param (fiasco_c_options_t *options,
+				  unsigned frames_per_second,
+				  int half_pixel_prediction,
+				  int cross_B_search,
+				  int B_as_past_ref)
+/*
+ *  Set various parameters used for video compensation.
+ *  'frames_per_second' defines the frame rate which should be
+ *  used when the video is decoded. This value has no effect during coding,
+ *  it is just passed to the FIASCO output file.
+ *  If 'half_pixel_prediction' is not 0 then half pixel precise
+ *  motion compensated prediction is used.
+ *  If 'cross_B_search' is not 0 then the fast Cross-B-Search algorithm is
+ *  used to determine the motion vectors of interpolated prediction. Otherwise
+ *  exhaustive search (in the given search range) is used.
+ *  If 'B_as_past_ref' is not 0 then B frames are allowed to be used
+ *  for B frame predicion.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else
+   {
+      this->fps 	  	  = frames_per_second;
+      this->half_pixel_prediction = half_pixel_prediction;
+      this->cross_B_search 	  = cross_B_search;
+      this->B_as_past_ref 	  = B_as_past_ref;
+
+      return 1;
+   }
+}
+
+int
+fiasco_c_options_set_quantization (fiasco_c_options_t *options,
+				   unsigned mantissa,
+				   fiasco_rpf_range_e range,
+				   unsigned dc_mantissa,
+				   fiasco_rpf_range_e dc_range)
+/*
+ *  Set accuracy of coefficients quantization.
+ *  DC coefficients (of the constant dictionary vector f(x,y) = 1)
+ *  are quantized to values of the interval [-`dc_range', `dc_range'] using
+ *  #`dc_mantissa' bits. All other quantized coefficients are quantized in
+ *  an analogous way using the parameters `range' and `mantissa'.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (mantissa < 2 || mantissa > 8 || dc_mantissa < 2 || dc_mantissa > 8)
+   {
+      set_error (_("Number of RPF mantissa bits `%d', `%d' have to be in "
+		   "the interval [2,8]."), mantissa, dc_mantissa);
+      return 0;
+   }
+   else
+   {
+      if ((range == FIASCO_RPF_RANGE_0_75
+	  || range == FIASCO_RPF_RANGE_1_00
+	  || range == FIASCO_RPF_RANGE_1_50
+	   || range == FIASCO_RPF_RANGE_2_00)
+	  &&
+	  (dc_range == FIASCO_RPF_RANGE_0_75
+	   || dc_range == FIASCO_RPF_RANGE_1_00
+	   || dc_range == FIASCO_RPF_RANGE_1_50
+	   || dc_range == FIASCO_RPF_RANGE_2_00))
+      {
+	 this->rpf_range       = range;
+	 this->dc_rpf_range    = dc_range;
+	 this->rpf_mantissa    = mantissa;
+	 this->dc_rpf_mantissa = dc_mantissa;
+
+	 return 1;
+      }
+      else
+      {
+	 set_error (_("Invalid RPF ranges `%d', `%d' specified."),
+		    range, dc_range);
+	 return 0;
+      }
+   }
+}
+
+int
+fiasco_c_options_set_progress_meter (fiasco_c_options_t *options,
+				     fiasco_progress_e type)
+/*
+ *  Set type of progress meter.
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   switch (type)
+   {
+      case FIASCO_PROGRESS_BAR:
+      case FIASCO_PROGRESS_PERCENT:
+      case FIASCO_PROGRESS_NONE:
+	 this->progress_meter = type;
+	 break;
+      default:
+	 set_error (_("Invalid progress meter `%d' specified "
+		      "(valid values are 0, 1, or 2)."), type);
+	 return 0;
+   }
+   return 1;
+}
+
+int
+fiasco_c_options_set_smoothing (fiasco_c_options_t *options, int smoothing)
+/*
+ *  Define `smoothing'-percentage along partitioning borders.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (smoothing < -1 || smoothing > 100)
+   {
+      set_error (_("Smoothing percentage must be in the range [-1, 100]."));
+      return 0;
+   }
+   else
+   {
+      this->smoothing = smoothing;
+      return 1;
+   }
+}
+
+int
+fiasco_c_options_set_comment (fiasco_c_options_t *options, const char *comment)
+/*
+ *  Define `comment' of FIASCO stream.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (!comment)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "title");
+      return 0;
+   }
+   else
+   {
+      this->comment = strdup (comment);
+      return 1;
+   }
+}
+
+int
+fiasco_c_options_set_title (fiasco_c_options_t *options, const char *title)
+/*
+ *  Define `title' of FIASCO stream.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) cast_c_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (!title)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "title");
+      return 0;
+   }
+   else
+   {
+      this->title = strdup (title);
+      return 1;
+   }
+}
+
+c_options_t *
+cast_c_options (fiasco_c_options_t *options)
+/*
+ *  Cast generic pointer `options' to type c_options_t.
+ *  Check whether `options' is a valid object of type c_options_t.
+ *
+ *  Return value:
+ *	pointer to options struct on success
+ *      NULL otherwise
+ */
+{
+   c_options_t *this = (c_options_t *) options->private;
+   if (this)
+   {
+      if (!streq (this->id, "COFIASCO"))
+      {
+	 set_error (_("Parameter `options' doesn't match required type."));
+	 return NULL;
+      }
+   }
+   else
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "options");
+   }
+
+   return this;
+}
+
+/**************************************************************************
+***************************************************************************
+			       DECODER
+***************************************************************************
+**************************************************************************/
+
+fiasco_d_options_t *
+fiasco_d_options_new (void)
+/*
+ *  FIASCO options constructor.
+ *  Allocate memory for the FIASCO coder options structure and
+ *  fill in default values.
+ *
+ *  Return value:
+ *	pointer to the new option structure
+ */
+{
+   d_options_t 	      *options = calloc (1, sizeof (d_options_t));
+   fiasco_d_options_t *public  = calloc (1, sizeof (fiasco_d_options_t));
+
+   if (!options || !public)
+   {
+      set_error (_("Out of memory."));
+      return NULL;
+   }
+   public->private 	      = options;
+   public->delete 	      = fiasco_d_options_delete;
+   public->set_smoothing      = fiasco_d_options_set_smoothing;
+   public->set_magnification  = fiasco_d_options_set_magnification;
+   public->set_4_2_0_format   = fiasco_d_options_set_4_2_0_format;
+   
+   strcpy (options->id, "DOFIASCO");
+
+   /*
+    *  Set default value of fiasco decoder options
+    */
+   options->smoothing 	  = 70;
+   options->magnification = 0;
+   options->image_format  = FORMAT_4_4_4;
+   
+   return public;
+}
+
+void
+fiasco_d_options_delete (fiasco_d_options_t *options)
+/*
+ *  FIASCO options destructor.
+ *  Free memory of FIASCO options struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'options' is discarded.
+ */
+{
+   d_options_t *this = cast_d_options (options);
+
+   if (!this)
+      return;
+   
+   Free (this);
+
+   return;
+}
+
+int
+fiasco_d_options_set_smoothing (fiasco_d_options_t *options, int smoothing)
+/*
+ *  Define `smoothing'-percentage along partitioning borders.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   d_options_t *this = (d_options_t *) cast_d_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else if (smoothing < -1 || smoothing > 100)
+   {
+      set_error (_("Smoothing percentage must be in the range [-1, 100]."));
+      return 0;
+   }
+   else
+   {
+      this->smoothing = smoothing;
+      return 1;
+   }
+}
+
+int
+fiasco_d_options_set_magnification (fiasco_d_options_t *options, int level)
+/*
+ *  Set magnification-'level' of decoded image.
+ *  0: width x height of original image
+ *  1: (2 * width) x (2 * height) of original image
+ *  -1: (width / 2 ) x (height / 2) of original image
+ *  etc.
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   d_options_t *this = (d_options_t *) cast_d_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else
+   {
+      this->magnification = level;
+      return 1;
+   }
+}
+
+int
+fiasco_d_options_set_4_2_0_format (fiasco_d_options_t *options, int format)
+/*
+ *  Set image format to 4:2:0 or 4:4:4.
+ *  
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ */
+{
+   d_options_t *this = (d_options_t *) cast_d_options (options);
+
+   if (!this)
+   {
+      return 0;
+   }
+   else
+   {
+      this->image_format = format ? FORMAT_4_2_0 : FORMAT_4_4_4;
+      return 1;
+   }
+}
+
+d_options_t *
+cast_d_options (fiasco_d_options_t *options)
+/*
+ *  Cast generic pointer `options' to type d_options_t.
+ *  Check whether `options' is a valid object of type d_options_t.
+ *
+ *  Return value:
+ *	pointer to options struct on success
+ *      NULL otherwise
+ */
+{
+   d_options_t *this = (d_options_t *) options->private;
+   
+   if (this)
+   {
+      if (!streq (this->id, "DOFIASCO"))
+      {
+	 set_error (_("Parameter `options' doesn't match required type."));
+	 return NULL;
+      }
+   }
+   else
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "options");
+   }
+
+   return this;
+}
+
+
diff --git a/converter/other/fiasco/codec/options.h b/converter/other/fiasco/codec/options.h
new file mode 100644
index 00000000..3af6be01
--- /dev/null
+++ b/converter/other/fiasco/codec/options.h
@@ -0,0 +1,80 @@
+/*
+ *  options.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/10/28 17:39:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.4 $
+ *  $State: Exp $
+ */
+
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+typedef struct c_options
+{
+   char      	       id [9];
+   char  	      *basis_name;
+   unsigned  	       lc_min_level;
+   unsigned  	       lc_max_level;
+   unsigned  	       p_min_level;
+   unsigned  	       p_max_level;
+   unsigned  	       images_level;
+   unsigned  	       max_states;
+   unsigned  	       chroma_max_states;
+   unsigned  	       max_elements;
+   unsigned  	       tiling_exponent;
+   fiasco_tiling_e     tiling_method;
+   char        	      *id_domain_pool;
+   char        	      *id_d_domain_pool;
+   char        	      *id_rpf_model;
+   char        	      *id_d_rpf_model;
+   unsigned  	       rpf_mantissa;
+   real_t    	       rpf_range;
+   unsigned  	       dc_rpf_mantissa;
+   fiasco_rpf_range_e  dc_rpf_range;
+   unsigned  	       d_rpf_mantissa;
+   fiasco_rpf_range_e  d_rpf_range;
+   unsigned  	       d_dc_rpf_mantissa;
+   fiasco_rpf_range_e  d_dc_rpf_range;
+   real_t    	       chroma_decrease;
+   bool_t    	       prediction;
+   bool_t    	       delta_domains;
+   bool_t    	       normal_domains;
+   unsigned  	       search_range;
+   unsigned  	       fps;
+   char        	      *pattern;
+   char        	      *reference_filename;
+   bool_t    	       half_pixel_prediction;
+   bool_t    	       cross_B_search;
+   bool_t    	       B_as_past_ref;
+   bool_t    	       check_for_underflow;
+   bool_t    	       check_for_overflow;
+   bool_t    	       second_domain_block;
+   bool_t    	       full_search;
+   fiasco_progress_e   progress_meter;
+   char 	      *title;
+   char 	      *comment;
+   unsigned    	       smoothing;
+} c_options_t;
+
+typedef struct d_options
+{
+   char     id [9];
+   unsigned smoothing;
+   unsigned magnification;
+   format_e image_format;
+} d_options_t;
+
+c_options_t *
+cast_c_options (fiasco_c_options_t *options);
+d_options_t *
+cast_d_options (fiasco_d_options_t *options);
+
+#endif /* not _OPTIONS_H */
diff --git a/converter/other/fiasco/codec/prediction.c b/converter/other/fiasco/codec/prediction.c
new file mode 100644
index 00000000..351ba9df
--- /dev/null
+++ b/converter/other/fiasco/codec/prediction.c
@@ -0,0 +1,629 @@
+/*
+ *  prediction.c:	Range image prediction with MC or ND	
+ *
+ *  Written by:		Ullrich Hafner
+ *			Michael Unger
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "cwfa.h"
+#include "ip.h"
+#include "control.h"
+#include "misc.h"
+#include "subdivide.h"
+#include "bintree.h"
+#include "domain-pool.h"
+#include "approx.h"
+#include "wfalib.h"
+#include "mwfa.h"
+#include "prediction.h"
+
+#include "decoder.h"
+
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+typedef struct state_data
+{
+   real_t final_distribution;
+   byte_t level_of_state;
+   byte_t domain_type;
+
+   real_t *images_of_state;
+   real_t *inner_products;
+   real_t *ip_states_state [MAXLEVEL];
+
+   word_t tree [MAXLABELS];
+   mv_t	  mv_tree [MAXLABELS];
+   word_t y_state [MAXLABELS];
+   byte_t y_column [MAXLABELS];
+   byte_t prediction [MAXLABELS];
+
+   u_word_t x [MAXLABELS];
+   u_word_t y [MAXLABELS];
+
+   real_t weight [MAXLABELS][MAXEDGES + 1];
+   word_t int_weight [MAXLABELS][MAXEDGES + 1];
+   word_t into [MAXLABELS][MAXEDGES + 1];
+} state_data_t;
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static real_t
+nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
+	       range_t *range, wfa_t *wfa, coding_t *c);
+static real_t
+mc_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
+	       range_t *range, wfa_t *wfa, coding_t *c);
+static state_data_t *
+store_state_data (unsigned from, unsigned to, unsigned max_level,
+		  wfa_t *wfa, coding_t *c);
+static void
+restore_state_data (unsigned from, unsigned to, unsigned max_level,
+		    state_data_t *data, wfa_t *wfa, coding_t *c);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+ 
+real_t
+predict_range (real_t max_costs, real_t price, range_t *range, wfa_t *wfa,
+	       coding_t *c, unsigned band, int y_state, unsigned states,
+	       const tree_t *tree_model, const tree_t *p_tree_model,
+	       const void *domain_model, const void *d_domain_model,
+	       const void *coeff_model, const void *d_coeff_model)
+{
+   unsigned	 state;		     	/* counter */
+   void		*rec_domain_model;   	/* domain model after recursion */
+   void		*rec_d_domain_model; 	/* p domain model after recursion */
+   void		*rec_coeff_model;    	/* coeff model after recursion */
+   void		*rec_d_coeff_model;  	/* d coeff model after recursion */
+   tree_t	 rec_tree_model;	/* tree_model after '' */
+   tree_t	 rec_p_tree_model;    	/* p_tree_model after '' */
+   unsigned	 rec_states;	     	/* wfa->states after '' */
+   real_t	*rec_pixels;	     	/* c->pixels after '' */
+   state_data_t	*rec_state_data;     	/* state_data struct after '' */
+   real_t	 costs;		     	/* current approximation costs */
+   unsigned	 level;		     	/* counter */
+   state_data_t	*sd;		     	/* pointer to state_data field */
+
+   /*
+    *  Store WFA data from state 'lc_states' to 'wfa->states' - 1 and
+    *  current state of probability models.
+    */
+   rec_domain_model   = c->domain_pool->model;
+   rec_d_domain_model = c->d_domain_pool->model;
+   rec_coeff_model    = c->coeff->model;
+   rec_d_coeff_model  = c->d_coeff->model;
+   rec_tree_model     = c->tree;
+   rec_p_tree_model   = c->p_tree;
+   rec_states         = wfa->states;	
+   rec_pixels         = c->pixels;
+   rec_state_data     = store_state_data (states, rec_states - 1,
+					  c->options.lc_max_level, wfa, c);
+   
+   /*
+    *  Restore probability models to the state before the recursive subdivision
+    *  has been started.
+    */
+   wfa->states             = states;
+   c->tree                 = *tree_model;
+   c->p_tree               = *p_tree_model;
+   c->domain_pool->model   = c->domain_pool->model_duplicate (domain_model);
+   c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model);
+   c->coeff->model   	   = c->coeff->model_duplicate (c->coeff, coeff_model);
+   c->d_coeff->model   	   = c->d_coeff->model_duplicate (c->d_coeff,
+							  d_coeff_model);
+   
+   if (c->mt->frame_type == I_FRAME)
+      costs = nd_prediction (max_costs, price, band, y_state, range, wfa, c); 
+   else
+      costs = mc_prediction (max_costs, price, band, y_state, range, wfa, c);
+   
+   c->pixels = rec_pixels;
+   
+   if (costs < MAXCOSTS)
+   {
+      /*
+       *  Free the memory used by the state_data struct
+       */
+      for (state = states; state < rec_states; state++)
+      {
+	 sd = &rec_state_data [state - states];
+	 for (level = c->options.images_level + 1;
+	      level <= c->options.lc_max_level; level++)
+	    if (sd->ip_states_state [level] != NULL)
+	       Free (sd->ip_states_state [level]);
+	 if (sd->images_of_state != NULL)
+	    Free (sd->images_of_state);
+	 if (sd->inner_products != NULL)
+	    Free (sd->inner_products);
+      }
+      if (states < rec_states)
+	 Free (rec_state_data);
+      c->domain_pool->model_free (rec_domain_model);
+      c->d_domain_pool->model_free (rec_d_domain_model);
+      c->coeff->model_free (rec_coeff_model);
+      c->d_coeff->model_free (rec_d_coeff_model);
+
+      costs = (range->tree_bits + range->matrix_bits + range->weights_bits
+	       + range->mv_tree_bits + range->mv_coord_bits
+	       + range->nd_tree_bits + range->nd_weights_bits) * price
+	      + range->err;
+   }
+   else
+   {
+      /*
+       *  Restore WFA to state before function was called
+       */
+      c->domain_pool->model_free (c->domain_pool->model);
+      c->d_domain_pool->model_free (c->d_domain_pool->model);
+      c->coeff->model_free (c->coeff->model);
+      c->d_coeff->model_free (c->d_coeff->model);
+      
+      c->domain_pool->model   = rec_domain_model;
+      c->d_domain_pool->model = rec_d_domain_model;
+      c->coeff->model         = rec_coeff_model;
+      c->d_coeff->model       = rec_d_coeff_model;
+      c->tree                 = rec_tree_model;
+      c->p_tree               = rec_p_tree_model;
+      
+      range->prediction = NO;
+      
+      if (wfa->states != states)
+	 remove_states (states, wfa);
+      restore_state_data (states, rec_states - 1, c->options.lc_max_level,
+			  rec_state_data, wfa, c);
+      costs = MAXCOSTS;
+   }
+ 
+   return costs;
+} 
+
+void
+clear_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)
+/*
+ *  Clear norms arrays.
+ *
+ *  No return value.
+ */
+{
+   unsigned  range_size = wi->half_pixel
+			  ? square (wi->search_range)
+			  : square (2 * wi->search_range);
+
+   if (level > wi->p_min_level)
+   {
+      memset (mt->mc_forward_norms [level], 0, range_size * sizeof(real_t));
+      memset (mt->mc_backward_norms [level], 0, range_size * sizeof(real_t));
+   }
+}
+
+void
+update_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)
+/*
+ *  Norms table of levels larger than the bottom level are computed
+ *  by summing up previously calculated displacement costs of lower levels.
+ *
+ *  No return value.
+ */
+{
+   unsigned  range_size = wi->half_pixel
+			  ? square (wi->search_range)
+			  : square (2 * wi->search_range);
+   
+   if (level > wi->p_min_level)
+   {
+      unsigned index;			/* index of motion vector */
+      
+      for (index = 0; index < range_size; index++)
+	 mt->mc_forward_norms [level][index]
+	    += mt->mc_forward_norms [level - 1][index];
+      if (mt->frame_type == B_FRAME)
+	 for (index = 0; index < range_size; index++)
+	    mt->mc_backward_norms [level][index]
+	       += mt->mc_backward_norms [level - 1][index];
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static real_t
+mc_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
+	       range_t *range, wfa_t *wfa, coding_t *c)
+{
+   real_t    costs;		   	/* current approximation costs */
+   range_t   prange = *range;
+   unsigned  width  = width_of_level (range->level);
+   unsigned  height = height_of_level (range->level);
+   word_t   *mcpe   = Calloc (width * height, sizeof (word_t));
+
+   /*
+    *  If we are at the bottom level of the mc tree:
+    *  Fill in the norms table
+    */
+   if (prange.level == wfa->wfainfo->p_min_level) 
+      fill_norms_table (prange.x, prange.y, prange.level, wfa->wfainfo, c->mt);
+   /*
+    *  Predict 'range' with motion compensation according to frame type.
+    *  MCPE is returned in 'c->mcpe'
+    */
+   if (c->mt->frame_type == P_FRAME)
+      find_P_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt);
+   else
+      find_B_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt);
+   
+   costs = (prange.mv_tree_bits + prange.mv_coord_bits) * price;
+   
+   if (costs < max_costs)		/* motion vector not too expensive */
+   {
+      unsigned  last_state;		/* last WFA state before recursion */
+      real_t   *ipi [MAXSTATES];	/* inner products pointers */
+      unsigned  state;
+      real_t  	mvt, mvc;
+      
+      c->pixels = Calloc (width * height, sizeof (real_t));
+      cut_to_bintree (c->pixels, mcpe, width, height, 0, 0, width, height);
+   
+      /*
+       *  Approximate MCPE recursively.
+       */
+      last_state = wfa->states - 1;
+      for (state = 0; state <= last_state; state++)
+	 if (need_image (state, wfa))
+	 {
+	    ipi [state] = c->ip_images_state[state];
+	    c->ip_images_state[state]
+	       = Calloc (size_of_tree (c->products_level), sizeof (real_t));
+	 }
+
+      mvc = prange.mv_coord_bits;
+      mvt = prange.mv_tree_bits;
+      
+      prange.image           = 0;
+      prange.address         = 0;
+      prange.tree_bits       = 0;
+      prange.matrix_bits     = 0;
+      prange.weights_bits    = 0;
+      prange.mv_coord_bits   = 0;
+      prange.mv_tree_bits    = 0;
+      prange.nd_weights_bits = 0;
+      prange.nd_tree_bits    = 0;
+
+      compute_ip_images_state (prange.image, prange.address, prange.level,
+			       1, 0, wfa, c);
+      costs += subdivide (max_costs - costs, band, y_state, &prange,
+			  wfa, c, NO, YES);
+
+      if (costs < max_costs)		/* use motion compensation */
+      {
+	 unsigned img, adr;		/* temp. values */
+	 
+	 img                  = range->image;
+	 adr                  = range->address;
+	 *range               = prange;
+	 range->image         = img;
+	 range->address       = adr;
+	 range->mv_coord_bits = mvc;
+	 range->mv_tree_bits  = mvt;
+	 range->prediction    = YES;
+
+	 for (state = last_state + 1; state < wfa->states; state++)
+	    if (need_image (state, wfa))
+	       memset (c->ip_images_state [state], 0,
+		       size_of_tree (c->products_level) * sizeof (real_t));
+
+	 costs = (range->tree_bits + range->matrix_bits + range->weights_bits
+		  + range->mv_tree_bits + range->mv_coord_bits
+		  + range->nd_tree_bits + range->nd_weights_bits) * price
+		 + range->err;
+      }
+      else
+	 costs = MAXCOSTS;
+
+      for (state = 0; state <= last_state; state++)
+	 if (need_image (state, wfa))
+	 {
+	    Free (c->ip_images_state[state]);
+	    c->ip_images_state[state] = ipi [state];
+	 }
+      Free (c->pixels);
+   }
+   else
+      costs = MAXCOSTS;
+   
+   Free (mcpe);
+
+   return costs;
+}
+
+static real_t
+nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
+	       range_t *range, wfa_t *wfa, coding_t *c)
+{
+   real_t  costs;			/* current approximation costs */
+   range_t lrange = *range;
+   
+   /*
+    *  Predict 'range' with DC component approximation
+    */
+   {
+      real_t x = get_ip_image_state (range->image, range->address,
+				     range->level, 0, c);
+      real_t y = get_ip_state_state (0, 0, range->level, c);
+      real_t w = btor (rtob (x / y, c->coeff->dc_rpf), c->coeff->dc_rpf);
+      word_t s [2] = {0, -1};
+
+      lrange.into [0] 	     = 0;
+      lrange.into [1] 	     = NO_EDGE;
+      lrange.weight [0]      = w;
+      lrange.mv_coord_bits   = 0;
+      lrange.mv_tree_bits    = 0;
+      lrange.nd_tree_bits    = tree_bits (LEAF, lrange.level, &c->p_tree);
+      lrange.nd_weights_bits = 0;
+      lrange.tree_bits       = 0;
+      lrange.matrix_bits     = 0;
+      lrange.weights_bits    = c->coeff->bits (&w, s, range->level, c->coeff);
+   }
+   costs = price * (lrange.weights_bits + lrange.nd_tree_bits);
+   
+   /*
+    *  Recursive aproximation of difference image
+    */
+   if (costs < max_costs)		
+   {
+      unsigned  state;
+      range_t  	rrange;			/* range: recursive subdivision */
+      unsigned  last_state;		/* last WFA state before recursion */
+      real_t   *ipi [MAXSTATES];	/* inner products pointers */
+      unsigned 	width  = width_of_level (range->level);
+      unsigned  height = height_of_level (range->level);
+      real_t   *pixels;
+
+      /*
+       *  Generate difference image original - approximation
+       */
+      {
+	 unsigned  n;
+	 real_t *src, *dst;		/* pointers to image data */
+	 real_t w = - lrange.weight [0] * c->images_of_state [0][0];
+		     
+	 src = c->pixels + range->address * size_of_level (range->level); 
+	 dst = c->pixels = pixels = Calloc (width * height, sizeof (real_t));
+
+	 for (n = width * height; n; n--)
+	    *dst++ = *src++ + w;
+      }
+      
+      /*
+       *  Approximate difference recursively.
+       */
+      rrange                 = *range;
+      rrange.tree_bits       = 0;
+      rrange.matrix_bits     = 0;
+      rrange.weights_bits    = 0;
+      rrange.mv_coord_bits   = 0;
+      rrange.mv_tree_bits    = 0;
+      rrange.nd_tree_bits    = 0;
+      rrange.nd_weights_bits = 0;
+      rrange.image           = 0;
+      rrange.address         = 0;
+
+      last_state = wfa->states - 1;
+      for (state = 0; state <= last_state; state++)
+	 if (need_image (state, wfa))
+	 {
+	    ipi [state] = c->ip_images_state[state];
+	    c->ip_images_state[state]
+	       = Calloc (size_of_tree (c->products_level), sizeof (real_t));
+	 }
+      
+      compute_ip_images_state (rrange.image, rrange.address, rrange.level,
+			       1, 0, wfa, c);
+      
+      costs += subdivide (max_costs - costs, band, y_state, &rrange, wfa, c,
+			  NO, YES);
+      
+      Free (pixels);
+
+      if (costs < max_costs && ischild (rrange.tree)) /* use prediction */
+      {
+	 unsigned img, adr;
+	 unsigned edge;
+
+	 img                     = range->image;
+	 adr                     = range->address;
+	 *range                  = rrange;
+	 range->image            = img;
+	 range->address          = adr;
+	 range->nd_tree_bits    += lrange.nd_tree_bits;
+	 range->nd_weights_bits += lrange.weights_bits;
+	 
+	 for (edge = 0; isedge (lrange.into [edge]); edge++)
+	 {
+	    range->into [edge]   = lrange.into [edge];
+	    range->weight [edge] = lrange.weight [edge];
+	 }
+	 range->into [edge] = NO_EDGE;
+	 range->prediction  = edge;
+
+	 for (state = last_state + 1; state < wfa->states; state++)
+	    if (need_image (state, wfa))
+	       memset (c->ip_images_state [state], 0,
+		       size_of_tree (c->products_level) * sizeof (real_t));
+      }
+      else
+	 costs = MAXCOSTS;
+      
+      for (state = 0; state <= last_state; state++)
+	 if (need_image (state, wfa))
+	 {
+	    Free (c->ip_images_state [state]);
+	    c->ip_images_state [state] = ipi [state];
+	 }
+   }
+   else
+      costs = MAXCOSTS;
+
+   return costs;
+}
+
+static state_data_t *
+store_state_data (unsigned from, unsigned to, unsigned max_level,
+		  wfa_t *wfa, coding_t *c)
+/*
+ *  Save and remove all states starting from state 'from'.
+ *
+ *  Return value:
+ *	pointer to array of state_data structs
+ */
+{
+   state_data_t *data;			/* array of savestates */
+   state_data_t *sd;			/* pointer to current savestates */
+   unsigned	 state, label, level;
+
+   if (to < from)
+      return NULL;			/* nothing to do */
+   
+   data = Calloc (to - from + 1, sizeof (state_data_t));
+   
+   for (state = from; state <= to; state++)
+   {
+      sd = &data [state - from];
+
+      sd->final_distribution = wfa->final_distribution [state];
+      sd->level_of_state     = wfa->level_of_state [state];
+      sd->domain_type        = wfa->domain_type [state];
+      sd->images_of_state    = c->images_of_state [state];
+      sd->inner_products     = c->ip_images_state [state];
+      
+      wfa->domain_type [state]   = 0;
+      c->images_of_state [state] = NULL;
+      c->ip_images_state [state] = NULL;
+				   
+      for (label = 0; label < MAXLABELS; label++) 
+      {
+	 sd->tree [label]     	= wfa->tree [state][label];
+	 sd->y_state [label]  	= wfa->y_state [state][label];
+	 sd->y_column [label] 	= wfa->y_column [state][label];
+	 sd->mv_tree [label]  	= wfa->mv_tree [state][label];
+	 sd->x [label]        	= wfa->x [state][label];
+	 sd->y [label]        	= wfa->y [state][label];
+	 sd->prediction [label] = wfa->prediction [state][label];
+
+	 memcpy (sd->weight [label], wfa->weight [state][label], 
+		 sizeof (real_t) * (MAXEDGES + 1));
+	 memcpy (sd->int_weight [label], wfa->int_weight [state][label], 
+		 sizeof (word_t) * (MAXEDGES + 1));
+	 memcpy (sd->into [label], wfa->into [state][label], 
+		 sizeof (word_t) * (MAXEDGES + 1));
+
+	 wfa->into [state][label][0] = NO_EDGE;
+	 wfa->tree [state][label]    = RANGE;
+	 wfa->y_state [state][label] = RANGE;
+      }
+      for (level = c->options.images_level + 1; level <= max_level;
+	   level++)
+      {
+	 sd->ip_states_state [level]       = c->ip_states_state [state][level];
+	 c->ip_states_state [state][level] = NULL;
+      }
+   }
+
+   return data;
+}
+
+static void
+restore_state_data (unsigned from, unsigned to, unsigned max_level,
+		    state_data_t *data, wfa_t *wfa, coding_t *c)
+/*
+ *  Restore all state data starting from state 'from'.
+ *  
+ *  No return value.
+ */
+{
+   state_data_t *sd;			/* pointer to state_data item */
+   unsigned	 state, label, level;
+
+   if (to < from)
+      return;				/* nothing to do */
+   
+   for (state = from; state <= to; state++)
+   {
+      sd = &data [state - from];
+      
+      wfa->final_distribution [state] = sd->final_distribution;
+      wfa->level_of_state [state]     = sd->level_of_state;
+      wfa->domain_type [state]        = sd->domain_type;
+      
+      if (c->images_of_state [state] != NULL)
+	 Free (c->images_of_state [state]);
+      c->images_of_state [state] = sd->images_of_state;
+      if (c->ip_images_state [state] != NULL)
+	 Free (c->ip_images_state [state]);
+      c->ip_images_state [state] = sd->inner_products;
+
+      for (label = 0; label < MAXLABELS; label++)
+      {
+	 wfa->tree [state][label]     	= sd->tree [label];
+	 wfa->y_state [state][label]  	= sd->y_state [label];
+	 wfa->y_column [state][label] 	= sd->y_column [label];
+	 wfa->mv_tree [state][label]  	= sd->mv_tree [label];
+	 wfa->x [state][label]        	= sd->x [label];
+	 wfa->y [state][label]        	= sd->y [label];
+	 wfa->prediction [state][label] = sd->prediction [label];
+	 
+	 memcpy (wfa->weight [state][label], sd->weight [label], 
+		 sizeof(real_t) * (MAXEDGES + 1));
+	 memcpy (wfa->int_weight [state][label], sd->int_weight [label], 
+		 sizeof(word_t) * (MAXEDGES + 1));
+	 memcpy (wfa->into [state][label], sd->into [label],  
+		 sizeof(word_t) * (MAXEDGES + 1));
+      }	 
+      for (level = c->options.images_level + 1; level <= max_level;
+	   level++)
+      {
+	 if (c->ip_states_state [state][level] != NULL)
+	    Free (c->ip_states_state [state][level]);
+	 c->ip_states_state [state][level] = sd->ip_states_state [level];
+      }
+   }
+
+   Free (data);
+   wfa->states = to + 1;
+}
diff --git a/converter/other/fiasco/codec/prediction.h b/converter/other/fiasco/codec/prediction.h
new file mode 100644
index 00000000..1068501a
--- /dev/null
+++ b/converter/other/fiasco/codec/prediction.h
@@ -0,0 +1,36 @@
+/*
+ *  prediction.h
+ *
+ *  Written by:		Ullrich Hafner
+ *			Michael Unger
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _PREDICTION_H
+#define _PREDICTION_H
+
+#include "types.h"
+#include "cwfa.h"
+
+real_t
+predict_range (real_t max_costs, real_t price, range_t *range, wfa_t *wfa,
+	       coding_t *c, unsigned band, int y_state, unsigned states,
+	       const tree_t *tree_model, const tree_t *p_tree_model,
+	       const void *domain_model, const void *d_domain_model,
+	       const void *coeff_model, const void *d_coeff_model);
+void
+update_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt);
+void
+clear_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt);
+
+#endif /* not _PREDICTION_H */
+
diff --git a/converter/other/fiasco/codec/subdivide.c b/converter/other/fiasco/codec/subdivide.c
new file mode 100644
index 00000000..b7982716
--- /dev/null
+++ b/converter/other/fiasco/codec/subdivide.c
@@ -0,0 +1,650 @@
+/*
+ *  subdivide.c:	Recursive subdivision of range images
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/15 17:59:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.4 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "image.h"
+#include "cwfa.h"
+#include "approx.h"
+#include "ip.h"
+#include "bintree.h"
+#include "control.h"
+#include "prediction.h"
+#include "domain-pool.h"
+#include "mwfa.h"
+#include "misc.h"
+#include "subdivide.h"
+#include "list.h"
+#include "coeff.h"
+#include "wfalib.h"
+
+/*****************************************************************************
+
+				prototypes
+
+*****************************************************************************/
+
+static void
+init_new_state (bool_t auxiliary_state, bool_t delta, range_t *range,
+		const range_t *child, const int *y_state,
+		wfa_t *wfa, coding_t *c);
+static void
+init_range (range_t *range, const image_t *image, unsigned band,
+	    const wfa_t *wfa, coding_t *c);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+real_t 
+subdivide (real_t max_costs, unsigned band, int y_state, range_t *range,
+	   wfa_t *wfa, coding_t *c, bool_t prediction, bool_t delta)
+/*
+ *  Subdivide the current 'range' recursively and decide whether
+ *  a linear combination, a recursive subdivision, or a prediction is
+ *  the best choice of approximation.
+ *  'band' is the current color band, 'y_state' is the corresponding
+ *  state of the Y color component (color image compression only).
+ *  If 'prediction' is TRUE then also test motion compensation or
+ *  nondeterministic approximation.
+ *  If 'delta' is TRUE then current range is already predicted.
+ *  
+ *  Return value:
+ *	costs of the best approximation or MAXCOSTS if costs exceed 'max_costs'
+ *
+ *  Side effects:
+ *	'range'	factors and costs of linear combination are modified
+ *      'wfa'	new transitions and prediction coefficients are added
+ *	'c'	pixels and inner products are updated
+ */
+{
+   real_t    subdivide_costs;        /* Costs arising from approx. the current
+				       range with two childs */
+   real_t    lincomb_costs;          /* Costs arising from approx. the current
+				       range with a linear combination */
+   int	     new_y_state [MAXLABELS];	/* Corresponding state of Y */
+   real_t    price;			/* Approximation costs multiplier */
+   bool_t    try_mc;			/* YES: try MC prediction */
+   bool_t    try_nd;			/* YES: try ND prediction */
+   unsigned  states;			/* Number of states before the
+					   recursive subdivision starts */
+   void     *domain_model;		/* copy of domain pool model */      
+   void     *d_domain_model;		/* copy of delta domain pool model */
+   void     *lc_domain_model;		/* copy of domain pool model */
+   void     *lc_d_domain_model;		/* copy of delta domain pool model */
+   void	    *coeff_model;	        /* copy of coefficients model */
+   void	    *d_coeff_model;		/* copy of delta coefficients model */
+   void	    *lc_coeff_model;	        /* copy of coefficients model */
+   void	    *lc_d_coeff_model;		/* copy of delta coefficients model */
+   tree_t    tree_model;		/* copy of tree model */
+   tree_t    p_tree_model;		/* copy of pred. tree model */
+   range_t   lrange;			/* range of lin. comb. approx. */
+   range_t   rrange;			/* range of recursive approx. */
+   range_t   child [MAXLABELS];		/* new childs of the current range */
+   static unsigned percent = 0;		/* status of progress meter */
+
+   if (wfa->wfainfo->level == range->level)
+      percent = 0;
+   
+   range->into [0] = NO_EDGE;		/* default approximation: empty */
+   range->tree     = RANGE;
+
+   if (range->level < 3)		/* Don't process small ranges */
+      return MAXCOSTS;	
+
+   /*
+    *  If image permutation (tiling) is performed and the tiling level
+    *  is reached then get coordinates of the new block.
+    */
+   if (c->tiling->exponent
+       && range->level == wfa->wfainfo->level - c->tiling->exponent)
+   {
+      unsigned width, height;		/* size of range (dummies)*/
+      
+      if (c->tiling->vorder [range->global_address] < 0)
+	 return 0;			/* nothing to do */
+      else
+	 locate_subimage (wfa->wfainfo->level, range->level,
+			  c->tiling->vorder [range->global_address],
+			  &range->x, &range->y, &width, &height);
+   }
+
+   if (range->x >= c->mt->original->width ||
+       range->y >= c->mt->original->height)
+      return 0;				/* range is not visible */
+
+   /*
+    *  Check whether prediction is allowed or not
+    *  mc == motion compensation, nd == nondeterminism
+    */
+   try_mc = (prediction && c->mt->frame_type != I_FRAME			
+	     && range->level >= wfa->wfainfo->p_min_level
+	     && range->level <= wfa->wfainfo->p_max_level
+	     && (range->x + width_of_level (range->level)
+		 <= c->mt->original->width)
+	     && (range->y + height_of_level (range->level)
+		 <= c->mt->original->height));
+
+   try_nd = (prediction && c->mt->frame_type == I_FRAME
+	     && range->level >= wfa->wfainfo->p_min_level
+	     && range->level <= wfa->wfainfo->p_max_level);
+
+   if (try_mc)
+      clear_norms_table (range->level, wfa->wfainfo, c->mt);
+
+   
+   /*
+    *  Check if current range must be initialized. I.e. range pixels must
+    *  be copied from entire image to bintree pixel buffer. Moreover,
+    *  all inner products tables must be initialized.
+    */
+   if (range->level == c->options.lc_max_level)	
+      init_range (range, c->mt->original, band, wfa, c);
+   
+   price = c->price;
+   if (band != Y)			
+      price *= c->options.chroma_decrease; /* less quality for chroma bands */
+
+   /*
+    *  Compute childs of corresponding state in Y band
+    */
+   if (band != Y)			/* Cb and Cr bands only */
+   {
+      unsigned label;
+
+      for (label = 0; label < MAXLABELS; label++)
+	 if (ischild (y_state))
+	    new_y_state [label] = wfa->tree [y_state][label];
+	 else
+	    new_y_state [label] = RANGE;
+   }
+   else
+      new_y_state [0] = new_y_state [1] = RANGE;
+   
+   /*
+    *  Store contents of all models that may get modified during recursion
+    */
+   domain_model   = c->domain_pool->model_duplicate (c->domain_pool->model);
+   d_domain_model = c->d_domain_pool->model_duplicate (c->d_domain_pool->model);
+   coeff_model    = c->coeff->model_duplicate (c->coeff, c->coeff->model);
+   d_coeff_model  = c->d_coeff->model_duplicate (c->d_coeff, c->d_coeff->model);
+   tree_model     = c->tree;
+   p_tree_model   = c->p_tree;
+   states         = wfa->states;	
+   
+   /*
+    *  First alternative of range approximation:
+    *  Compute costs of linear combination.
+    */
+   if (range->level <= c->options.lc_max_level) /* range is small enough */
+   {
+      lrange                 = *range;
+      lrange.tree            = RANGE;
+      lrange.tree_bits       = tree_bits (LEAF, lrange.level, &c->tree);
+      lrange.matrix_bits     = 0;
+      lrange.weights_bits    = 0;
+      lrange.mv_tree_bits    = try_mc ? 1 : 0; /* mc allowed but not used */
+      lrange.mv_coord_bits   = 0;
+      lrange.nd_tree_bits    = 0;	
+      lrange.nd_weights_bits = 0;	
+      lrange.prediction	     = NO;
+      
+      lincomb_costs
+	 = approximate_range (max_costs, price, c->options.max_elements,
+			      y_state, &lrange,
+			      (delta ? c->d_domain_pool : c->domain_pool),
+			      (delta ? c->d_coeff : c->coeff), wfa, c);
+   }
+   else
+      lincomb_costs = MAXCOSTS;		
+
+   /*
+    *  Store contents of models that have been modified
+    *  by approximate_range () above ...
+    */
+   lc_domain_model   = c->domain_pool->model;
+   lc_d_domain_model = c->d_domain_pool->model;
+   lc_coeff_model    = c->coeff->model;
+   lc_d_coeff_model  = c->d_coeff->model;
+   /*
+    *  ... and restore them with values before lc
+    */
+   c->domain_pool->model   = c->domain_pool->model_duplicate (domain_model);
+   c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model);
+   c->coeff->model         = c->coeff->model_duplicate (c->coeff, coeff_model);
+   c->d_coeff->model       = c->d_coeff->model_duplicate (c->d_coeff,
+							  d_coeff_model);
+   
+   /*
+    *  Second alternative of range approximation:
+    *  Compute costs of recursive subdivision.
+    */
+   if (range->level > c->options.lc_min_level) /* range is large enough */
+   {
+      unsigned label;
+      
+      memset (&child [0], 0, 2 * sizeof (range_t)); /* initialize childs */
+
+      /*
+       *  Initialize a new range for recursive approximation
+       */
+      rrange                 = *range;
+      rrange.tree_bits       = tree_bits (CHILD, rrange.level, &c->tree);
+      rrange.matrix_bits     = 0;
+      rrange.weights_bits    = 0;
+      rrange.err             = 0;
+      rrange.mv_tree_bits    = try_mc ? 1 : 0;	/* mc allowed but not used */
+      rrange.mv_coord_bits   = 0;
+      rrange.nd_tree_bits    = try_nd ?
+			       tree_bits (CHILD, lrange.level, &c->p_tree): 0;
+      rrange.nd_weights_bits = 0;	
+      rrange.prediction	     = NO;
+
+      /*
+       *  Initialize the cost function and subdivide the current range.
+       *  Every child is approximated by a recursive call of subdivide()
+       */
+      subdivide_costs = (rrange.tree_bits + rrange.weights_bits
+			 + rrange.matrix_bits + rrange.mv_tree_bits
+			 + rrange.mv_coord_bits + rrange.nd_tree_bits
+			 + rrange.nd_weights_bits) * price;
+      
+      for (label = 0; label < MAXLABELS; label++) 
+      {
+	 real_t remaining_costs;	/* upper limit for next recursion */
+	 
+	 child[label].image          = rrange.image * MAXLABELS + label + 1;
+	 child[label].address        = rrange.address * MAXLABELS + label;
+	 child[label].global_address = rrange.global_address * MAXLABELS
+				       + label;
+	 child[label].level          = rrange.level - 1;
+	 child[label].x	= rrange.level & 1
+			  ? rrange.x
+			  : (rrange.x
+			     + label * width_of_level (rrange.level - 1));
+	 child[label].y = rrange.level & 1
+			  ? (rrange.y
+			     + label * height_of_level (rrange.level - 1))
+			  : rrange.y;
+	 
+	 /* 
+	  *  If neccessary compute the inner products of the new states
+	  *  (generated during the recursive approximation of child [0])
+	  */
+	 if (label && rrange.level <= c->options.lc_max_level)
+	    compute_ip_images_state (child[label].image, child[label].address,
+				     child[label].level, 1, states, wfa, c);
+	 /*
+	  *  Call subdivide() for both childs. 
+	  *  Abort the recursion if 'subdivide_costs' exceed 'lincomb_costs'
+	  *  or 'max_costs'.
+	  */
+	 remaining_costs = min (lincomb_costs, max_costs) - subdivide_costs;
+
+	 if (remaining_costs > 0)	/* still a way for improvement */
+	 {
+	    subdivide_costs += subdivide (remaining_costs, band,
+					  new_y_state [label], &child [label],
+					  wfa, c, prediction, delta);
+	 }
+	 else if (try_mc && child[label].level >= wfa->wfainfo->p_min_level)
+	 {
+	    fill_norms_table (child[label].x, child[label].y,
+			      child[label].level, wfa->wfainfo, c->mt);
+	 }
+	 
+	 if (try_mc)
+	    update_norms_table (rrange.level, wfa->wfainfo, c->mt);
+	 
+	 /*
+	  *  Update of progress meter
+	  */
+	 if (c->options.progress_meter != FIASCO_PROGRESS_NONE)
+	 {
+	    if (c->options.progress_meter == FIASCO_PROGRESS_PERCENT)
+	    {
+	       unsigned	new_percent; 	/* new status of progress meter */
+	 
+	       new_percent = (child[label].global_address + 1) * 100.0
+			     / (1 << (wfa->wfainfo->level - child[label].level));
+	       if (new_percent > percent)
+	       {
+		  percent = new_percent;
+		  info ("%3d%%  \r", percent);
+	       }
+	    }
+	    else if (c->options.progress_meter == FIASCO_PROGRESS_BAR)
+	    {
+	       unsigned	new_percent;	/* new status of progress meter */
+	 
+	       new_percent = (child[label].global_address + 1) * 50.0
+			     / (1 << (wfa->wfainfo->level
+				      - child[label].level));
+	       for (; new_percent > percent; percent++)
+	       {
+		  info ("#");
+	       }
+	    }
+	 }
+   
+	 /*
+	  *  If costs of subdivision exceed costs of linear combination 
+	  *  then abort recursion.
+	  */
+	 if (subdivide_costs >= min (lincomb_costs, max_costs)) 
+	 {
+	    subdivide_costs = MAXCOSTS;
+	    break; 
+	 }
+	 rrange.err             += child [label].err;
+	 rrange.tree_bits       += child [label].tree_bits;
+	 rrange.matrix_bits     += child [label].matrix_bits;
+	 rrange.weights_bits    += child [label].weights_bits;
+	 rrange.mv_tree_bits    += child [label].mv_tree_bits;
+	 rrange.mv_coord_bits   += child [label].mv_coord_bits;
+	 rrange.nd_weights_bits += child [label].nd_weights_bits;
+	 rrange.nd_tree_bits    += child [label].nd_tree_bits;
+
+	 tree_update (ischild (child [label].tree) ? CHILD : LEAF,
+		      child [label].level, &c->tree);
+	 tree_update (child [label].prediction ? LEAF : CHILD,
+		      child [label].level, &c->p_tree);
+      }
+   }
+   else
+      subdivide_costs = MAXCOSTS;
+
+   /*
+    *  Third alternative of range approximation:
+    *  Predict range via motion compensation or nondeterminism and 
+    *  approximate delta image. 
+    */
+   if (try_mc || try_nd)		/* try prediction */
+   {
+      real_t prediction_costs;	/* Costs arising from approx. the current
+				   range with prediction */
+
+      prediction_costs
+	 = predict_range (min (min (lincomb_costs, subdivide_costs),
+			       max_costs),
+			  price, range, wfa, c, band, y_state, states,
+			  &tree_model, &p_tree_model, domain_model,
+			  d_domain_model, coeff_model, d_coeff_model);
+      if (prediction_costs < MAXCOSTS)	/* prediction has smallest costs */
+      {
+	 c->domain_pool->model_free (domain_model);
+	 c->d_domain_pool->model_free (d_domain_model);
+	 c->domain_pool->model_free (lc_domain_model);
+	 c->d_domain_pool->model_free (lc_d_domain_model);
+	 c->coeff->model_free (coeff_model);
+	 c->d_coeff->model_free (d_coeff_model);
+	 c->coeff->model_free (lc_coeff_model);
+	 c->d_coeff->model_free (lc_d_coeff_model);
+	 
+	 return prediction_costs;
+      }
+   }
+
+   if (lincomb_costs >= MAXCOSTS && subdivide_costs >= MAXCOSTS)
+   {
+      /*
+       *  Return MAXCOSTS if neither a linear combination nor a recursive
+       *  subdivision yield costs less than 'max_costs'
+       */
+      c->domain_pool->model_free (c->domain_pool->model);
+      c->d_domain_pool->model_free (c->d_domain_pool->model);
+      c->domain_pool->model_free (lc_domain_model);
+      c->d_domain_pool->model_free (lc_d_domain_model);
+
+      c->coeff->model_free (c->coeff->model);
+      c->d_coeff->model_free (c->d_coeff->model);
+      c->coeff->model_free (lc_coeff_model);
+      c->d_coeff->model_free (lc_d_coeff_model);
+	 
+      c->domain_pool->model   = domain_model;
+      c->d_domain_pool->model = d_domain_model;
+      c->coeff->model	      = coeff_model;
+      c->d_coeff->model	      = d_coeff_model;
+      c->tree                 = tree_model;
+      c->p_tree               = p_tree_model;
+      
+      if (wfa->states != states)
+	 remove_states (states, wfa);
+
+      return MAXCOSTS;
+   }
+   else if (lincomb_costs < subdivide_costs) 
+   {
+      /*
+       *  Use the linear combination: The factors of the linear combination
+       *  are stored already in 'range', so revert the probability models
+       *  only. 
+       */
+      c->domain_pool->model_free (c->domain_pool->model);
+      c->d_domain_pool->model_free (c->d_domain_pool->model);
+      c->domain_pool->model_free (domain_model);
+      c->d_domain_pool->model_free (d_domain_model);
+
+      c->coeff->model_free (c->coeff->model);
+      c->d_coeff->model_free (c->d_coeff->model);
+      c->coeff->model_free (coeff_model);
+      c->d_coeff->model_free (d_coeff_model);
+      
+      c->domain_pool->model   = lc_domain_model;
+      c->d_domain_pool->model = lc_d_domain_model;
+      c->coeff->model	      = lc_coeff_model;
+      c->d_coeff->model	      = lc_d_coeff_model;
+      c->tree                 = tree_model;
+      c->p_tree               = p_tree_model;
+
+      *range = lrange;
+      
+      if (wfa->states != states)
+	 remove_states (states, wfa);
+
+      return lincomb_costs;
+   }
+   else
+   {
+      /*
+       *  Use the recursive subdivision: Generate a new state with transitions
+       *  given in child[].
+       *  Don't use state in linear combinations in any of the following cases:
+       *  - if color component is Cb or Cr
+       *  - if level of state > tiling level 
+       *  - if state is (partially) outside image geometry 
+       */
+      if (band > Y
+	  || (c->tiling->exponent
+	      && rrange.level > wfa->wfainfo->level - c->tiling->exponent)
+	  || (range->x + width_of_level (range->level)
+	      > c->mt->original->width)
+	  || (range->y + height_of_level (range->level)
+	      > c->mt->original->height))
+	 init_new_state (YES, delta, &rrange, child, new_y_state, wfa, c);
+      else
+	 init_new_state (NO, delta, &rrange, child, new_y_state, wfa, c);
+
+      *range = rrange;
+
+      c->domain_pool->model_free (domain_model);
+      c->d_domain_pool->model_free (d_domain_model);
+      c->domain_pool->model_free (lc_domain_model);
+      c->d_domain_pool->model_free (lc_d_domain_model);
+      c->coeff->model_free (coeff_model);
+      c->d_coeff->model_free (d_coeff_model);
+      c->coeff->model_free (lc_coeff_model);
+      c->d_coeff->model_free (lc_d_coeff_model);
+
+      return subdivide_costs;
+   }
+}
+
+void
+cut_to_bintree (real_t *dst, const word_t *src,
+		unsigned src_width, unsigned src_height,
+		unsigned x0, unsigned y0, unsigned width, unsigned height)
+/*
+ *  Cut region ('x0', 'y0', 'width', 'height') of the pixel array 'src'.
+ *  Size of image is given by 'src_width' x 'src_height'.
+ *  'dst' pixels are converted to bintree order and real format.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'dst []' is filled with corresponding region.
+ */
+{
+   const unsigned mask01      = 0x555555; /* binary ...010101010101 */
+   const unsigned mask10      = 0xaaaaaa; /* binary ...101010101010 */
+   const unsigned mask01plus1 = mask01 + 1; /* binary ...010101010110 */
+   const unsigned mask10plus1 = mask10 + 1; /* binary ...101010101011 */
+   unsigned  	  x, y;			/* pixel coordinates */
+   unsigned  	  xmask, ymask;		/* address conversion */
+
+   if (width != height && width != (height >> 1))
+      error ("Bintree cutting requires special type of images.");
+
+   ymask = 0;
+   for (y = y0; y < y0 + height; y++, ymask = (ymask + mask10plus1) & mask01)
+   {
+      xmask = 0;
+      for (x = x0; x < x0 + width; x++, xmask = (xmask + mask01plus1) & mask10)
+      {
+	 if (y >= src_height || x >= src_width)
+	    dst [xmask | ymask] = 0;
+	 else
+	    dst [xmask | ymask] = src [y * src_width + x] / 16;
+      }
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+init_new_state (bool_t auxiliary_state, bool_t delta, range_t *range,
+		const range_t *child, const int *y_state,
+		wfa_t *wfa, coding_t *c)
+/*
+ *  Initializes a new state with all parameters needed for the encoding step.
+ *  If flag 'auxiliary_state' is set then don't insert state into domain pools.
+ *  If flag 'delta' is set then state represents a delta image (prediction via
+ *  nondeterminism or motion compensation).
+ *  'range' the current range image,
+ *   'child []' the left and right childs of 'range'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	New state is appended to 'wfa' (and also its inner products and images
+ *      are computed and stored in 'c')
+ */
+{
+   unsigned label;
+   bool_t   state_is_domain = NO;
+
+   if (!auxiliary_state)
+   {
+      if (!delta || c->options.delta_domains)
+	 state_is_domain = c->domain_pool->append (wfa->states, range->level,
+						   wfa, c->domain_pool->model);
+      if (delta || c->options.normal_domains)
+	 state_is_domain = c->d_domain_pool->append (wfa->states, range->level,
+						     wfa,
+						     c->d_domain_pool->model)
+			   || state_is_domain;
+   }
+   else
+      state_is_domain = NO;
+   
+   range->into [0] = NO_EDGE;
+   range->tree     = wfa->states;
+   
+   for (label = 0; label < MAXLABELS; label++) 
+   {
+      wfa->tree [wfa->states][label]       = child [label].tree;
+      wfa->y_state [wfa->states][label]    = y_state [label];
+      wfa->mv_tree [wfa->states][label]    = child [label].mv;
+      wfa->x [wfa->states][label]          = child [label].x;
+      wfa->y [wfa->states][label]          = child [label].y;
+      wfa->prediction [wfa->states][label] = child [label].prediction;
+
+      append_transitions (wfa->states, label, child [label].weight,
+			  child [label].into, wfa);
+   }
+   wfa->delta_state [wfa->states] = delta;
+
+   if (range->err < 0)
+      warning ("Negative image norm: %f, %f", child [0].err, child [1].err);
+
+/*    state_is_domain = YES; */
+   
+   append_state (!state_is_domain,
+		 compute_final_distribution (wfa->states, wfa),
+		 range->level, wfa, c);
+}
+
+static void
+init_range (range_t *range, const image_t *image, unsigned band,
+	    const wfa_t *wfa, coding_t *c)
+/*
+ *  Read a new 'range' of the image 'image_name' (current color component
+ *  is 'band') and compute the new inner product arrays.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'c->pixels' are filled with pixel values of image block 
+ *	'c->ip_images_state' are computed with respect to new image block 
+ *	'range->address' and 'range->image' are initialized with zero
+ */
+{
+   unsigned state;
+   
+   /*
+    *  Clear already computed products
+    */
+   for (state = 0; state < wfa->states; state++)
+      if (need_image (state, wfa))
+	 memset (c->ip_images_state[state], 0,
+		 size_of_tree (c->products_level) * sizeof(real_t));
+
+   cut_to_bintree (c->pixels, image->pixels [band],
+		   image->width, image->height,
+		   range->x, range->y, width_of_level (range->level),
+		   height_of_level (range->level));
+   
+   range->address = range->image = 0;
+   compute_ip_images_state (0, 0, range->level, 1, 0, wfa, c);
+}
+
+
diff --git a/converter/other/fiasco/codec/subdivide.h b/converter/other/fiasco/codec/subdivide.h
new file mode 100644
index 00000000..b6840e58
--- /dev/null
+++ b/converter/other/fiasco/codec/subdivide.h
@@ -0,0 +1,33 @@
+/*
+ *  subdivide.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _SUBDIVIDE_H
+#define _SUBDIVIDE_H
+
+#include "types.h"
+#include "cwfa.h"
+
+real_t 
+subdivide (real_t max_costs, unsigned band, int y_state, range_t *range,
+	   wfa_t *wfa, coding_t *c, bool_t prediction, bool_t delta);
+void
+cut_to_bintree (real_t *dst, const word_t *src,
+		unsigned src_width, unsigned src_height,
+		unsigned x0, unsigned y0, unsigned width, unsigned height);
+
+#endif /* not _SUBDIVIDE_H */
+
+
diff --git a/converter/other/fiasco/codec/tiling.c b/converter/other/fiasco/codec/tiling.c
new file mode 100644
index 00000000..e820f7fb
--- /dev/null
+++ b/converter/other/fiasco/codec/tiling.c
@@ -0,0 +1,239 @@
+/*
+ *  tiling.c:		Subimage permutation
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "image.h"
+#include "misc.h"
+#include "wfalib.h"
+#include "tiling.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static int
+cmpdecvar (const void *value1, const void *value2);
+static int
+cmpincvar (const void *value1, const void *value2);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+typedef struct var_list
+{
+   int	  address;			/* bintree address */
+   real_t variance;			/* variance of tile */
+} var_list_t;
+
+tiling_t *
+alloc_tiling (fiasco_tiling_e method, unsigned tiling_exponent,
+	      unsigned image_level)
+/*
+ *  Image tiling constructor.
+ *  Allocate memory for the tiling_t structure.
+ *  `method' defines the tiling method (spiral or variance,
+ *  ascending or descending).
+ *  In case of invalid parameters, a structure with tiling.exponent == 0 is
+ *  returned. 
+ *
+ *  Return value
+ *	pointer to the new tiling structure on success
+ */
+{
+   tiling_t *tiling = Calloc (1, sizeof (tiling_t));
+
+   if ((int) image_level - (int) tiling_exponent < 6)
+   {
+      tiling_exponent = 6;
+      warning (_("Image tiles must be at least 8x8 pixels large.\n"
+		 "Setting tiling size to 8x8 pixels."));
+   }
+   
+   switch (method)
+   {
+      case FIASCO_TILING_SPIRAL_ASC:
+      case FIASCO_TILING_SPIRAL_DSC:
+      case FIASCO_TILING_VARIANCE_ASC:
+      case FIASCO_TILING_VARIANCE_DSC:
+	 tiling_exponent = tiling_exponent;
+	 break;
+      default:
+	 warning (_("Invalid tiling method specified. Disabling tiling."));
+	 tiling_exponent = 0;
+	 break;
+   }
+
+   return tiling;
+}
+
+void
+free_tiling (tiling_t *tiling)
+/*
+ *  Tiling struct destructor:
+ *  Free memory of 'tiling' struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'tiling' is discarded.
+ */
+{
+   if (tiling->vorder)
+      Free (tiling->vorder);
+   Free (tiling);
+}
+
+void
+perform_tiling (const image_t *image, tiling_t *tiling)
+/*
+ *  Compute image tiling permutation.
+ *  The image is split into 2**'tiling->exponent' tiles.
+ *  Depending on 'tiling->method', the following algorithms are used:
+ *  "VARIANCE_ASC" :  Tiles are sorted by variance.
+ *                    The first tile has the lowest variance
+ *  "VARIANCE_DSC" :  Tiles are sorted by variance.
+ *                    The first tile has the largest variance
+ *  "SPIRAL_ASC" :    Tiles are sorted like a spiral starting
+ *                    in the middle of the image.
+ *  "SPIRAL_DSC" :    Tiles are sorted like a spiral starting
+ *                    in the upper left corner.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	The tiling permutation is stored in 'tiling->vorder'.
+ */
+{
+   if (tiling->exponent)
+   {
+      unsigned 	tiles = 1 << tiling->exponent; /* number of image tiles */
+      bool_t   *tile_valid;		/* tile i is in valid range ? */
+      
+      tiling->vorder = Calloc (tiles, sizeof (int));
+      tile_valid     = Calloc (tiles, sizeof (bool_t));
+
+      if (tiling->method == FIASCO_TILING_VARIANCE_ASC
+	  || tiling->method == FIASCO_TILING_VARIANCE_DSC)
+      {
+	 unsigned    address;		/* bintree address of tile */
+	 unsigned    number;		/* number of image tiles */
+	 unsigned    lx       = log2 (image->width - 1) + 1; /* x level */
+	 unsigned    ly       = log2 (image->height - 1) + 1; /* y level */
+	 unsigned    level    = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0);
+	 var_list_t *var_list = Calloc (tiles, sizeof (var_list_t));
+	 
+	 /*
+	  *  Compute variances of image tiles
+	  */
+	 for (number = 0, address = 0; address < tiles; address++)
+	 {
+	    unsigned width, height;	/* size of image tile */
+	    unsigned x0, y0;		/* NW corner of image tile */
+      
+	    locate_subimage (level, level - tiling->exponent, address,
+			     &x0, &y0, &width, &height);
+	    if (x0 < image->width && y0 < image->height) /* valid range */
+	    {
+	       if (x0 + width > image->width)	/* outside image area */
+		  width = image->width - x0;
+	       if (y0 + height > image->height) /* outside image area */
+		  height = image->height - y0;
+
+	       var_list [number].variance
+		  = variance (image->pixels [GRAY], x0, y0,
+			      width, height, image->width);
+	       var_list [number].address  = address;
+	       number++;
+	       tile_valid [address] = YES;
+	    }
+	    else
+	       tile_valid [address] = NO;
+	 }
+
+	 /*
+	  *  Sort image tiles according to sign of 'tiling->exp'
+	  */
+	 if (tiling->method == FIASCO_TILING_VARIANCE_DSC)
+	    qsort (var_list, number, sizeof (var_list_t), cmpdecvar);
+	 else
+	    qsort (var_list, number, sizeof (var_list_t), cmpincvar);
+
+	 for (number = 0, address = 0; address < tiles; address++)
+	    if (tile_valid [address])
+	    {
+	       tiling->vorder [address] = var_list [number].address;
+	       number++;
+	       debug_message ("tile number %d has original address %d",
+			      number, tiling->vorder [address]);
+	    }
+	    else
+	       tiling->vorder [address] = -1;
+
+	 Free (var_list);
+      }
+      else if (tiling->method == FIASCO_TILING_SPIRAL_DSC
+	       || tiling->method == FIASCO_TILING_SPIRAL_ASC)
+      {
+	 compute_spiral (tiling->vorder, image->width, image->height,
+			 tiling->exponent,
+			 tiling->method == FIASCO_TILING_SPIRAL_ASC);
+      }
+      else
+      {
+	 warning ("Unsupported image tiling method.\n"
+		  "Skipping image tiling step.");
+	 tiling->exponent = 0;
+      }
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static int
+cmpincvar (const void *value1, const void *value2)
+/*
+ *  Sorts by increasing variances (quicksort sorting function).
+ */
+{
+  return ((var_list_t *) value1)->variance - ((var_list_t *) value2)->variance;
+}
+
+static int
+cmpdecvar (const void *value1, const void *value2)
+/*
+ *  Sorts by decreasing variances (quicksort sorting function).
+ */
+{
+  return ((var_list_t *) value2)->variance - ((var_list_t *) value1)->variance;
+}
diff --git a/converter/other/fiasco/codec/tiling.h b/converter/other/fiasco/codec/tiling.h
new file mode 100644
index 00000000..2eb04fe0
--- /dev/null
+++ b/converter/other/fiasco/codec/tiling.h
@@ -0,0 +1,40 @@
+/*
+ *  tiling.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _TILING_H
+#define _TILING_H
+
+#include "image.h"
+#include "fiasco.h"
+
+typedef struct tiling
+{
+   unsigned    	    exponent;		/* Image is split in 2^exp tiles */
+   fiasco_tiling_e  method;		/* Method of Image tiling */
+   int	      	   *vorder;		/* Block permutation (size = 2^exp)
+					   -1 indicates empty block */
+} tiling_t;
+
+void
+perform_tiling (const image_t *image, tiling_t *tiling);
+tiling_t *
+alloc_tiling (fiasco_tiling_e method, unsigned tiling_exponent,
+	      unsigned image_level);
+void
+free_tiling (tiling_t *tiling);
+
+#endif /* not _TILING_H */
+
diff --git a/converter/other/fiasco/codec/wfa.h b/converter/other/fiasco/codec/wfa.h
new file mode 100644
index 00000000..8b9793f2
--- /dev/null
+++ b/converter/other/fiasco/codec/wfa.h
@@ -0,0 +1,141 @@
+/*
+ *  wfa.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/18 15:44:57 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#ifndef _WFA_H
+#define _WFA_H
+
+#define MAXEDGES  5
+#define MAXSTATES 6000
+#define MAXLABELS 2			/* only bintree supported anymore */
+#define MAXLEVEL  22 
+
+#define FIASCO_BINFILE_RELEASE   2
+#define FIASCO_MAGIC	         "FIASCO" /* FIASCO magic number */
+#define FIASCO_BASIS_MAGIC       "Fiasco" /* FIASCO initial basis */
+
+#define NO_EDGE		-1
+#define RANGE		-1
+#define NO_RANGE	 0
+
+#define CHILD		 1
+#define LEAF		 0
+
+#define MAX_PROB	 9
+#define MIN_PROB	 1
+
+/*
+ *  WFA state types:
+ *	0:		 state is not allowed to be used in an
+ *			 approximation and it's image is not needed
+ *			 for ip computations.
+ *	AUXILIARY_MASK:  state is required for computation of ip's but is not
+ *			 allowed to be used in an approximation.
+ *	USE_DOMAIN_MASK: state is allowed to be used in an approximation.
+ */
+enum state_types {AUXILIARY_MASK = 1 << 0, USE_DOMAIN_MASK = 1 << 1};
+
+#define isedge(x)	   ((x) != NO_EDGE)
+#define isdomain(x)	   ((x) != NO_EDGE)
+#define isrange(x)	   ((x) == RANGE)
+#define ischild(x)	   ((x) != RANGE)
+#define isauxiliary(d,wfa) ((wfa)->domain_type[d] & AUXILIARY_MASK)
+#define usedomain(d, wfa)  ((wfa)->domain_type[d] & USE_DOMAIN_MASK)
+#define need_image(d,wfa)  (isauxiliary ((d), (wfa)) || usedomain ((d), (wfa)))
+
+typedef enum mc_type {NONE, FORWARD, BACKWARD, INTERPOLATED} mc_type_e;
+typedef enum frame_type {I_FRAME, P_FRAME, B_FRAME} frame_type_e;
+typedef enum header {HEADER_END, HEADER_TITLE, HEADER_COMMENT} header_type_e;
+
+typedef struct mv
+/*
+ *  Motion vector components
+ */
+{
+   mc_type_e type;			/* motion compensation type */
+   int       fx, fy;			/* forward vector coordinates */
+   int       bx, by;			/* backward vector coordinates */
+} mv_t;
+
+typedef struct range_info
+{
+   unsigned x, y;			/* coordinates of upper left corner */
+   unsigned level;			/* bintree level of range */
+} range_info_t;
+
+#include "image.h"
+#include "rpf.h"
+#include "bit-io.h"
+
+typedef struct wfa_info
+{
+   char	    *wfa_name;			/* filename of the WFA */
+   char	    *basis_name;		/* filename of the initial basis */
+   char     *title;			/* title of FIASCO stream */
+   char     *comment;			/* comment for FIASCO stream */
+   
+   unsigned  max_states;		/* max. cardinality of domain pool */
+   unsigned  chroma_max_states;		/* max. cardinality of domain pool for
+					   chroma band coding */
+   bool_t    color;			/* color image */
+   unsigned  width;			/* image width */
+   unsigned  height;			/* image height */
+   unsigned  level;			/* image level */
+   rpf_t    *rpf;			/* Standard reduced precision format */
+   rpf_t    *dc_rpf;			/* DC reduced precision format */
+   rpf_t    *d_rpf;			/* Delta reduced precision format */
+   rpf_t    *d_dc_rpf;			/* Delta DC reduced precision format */
+   unsigned  frames;			/* number of frames in the video */
+   unsigned  fps;			/* number of frames per second */
+   unsigned  p_min_level;		/* min. level of prediction */
+   unsigned  p_max_level;		/* max. level of prediction */
+   unsigned  search_range;		/* motion vector interval */
+   bool_t    half_pixel;		/* usage of half pixel precision */
+   bool_t    cross_B_search;		/* usage of Cross-B-Search */
+   bool_t    B_as_past_ref;		/* usage of B frames as ref's */
+   unsigned  smoothing;			/* smoothing of image along borders */
+   unsigned  release;			/* FIASCO file format release */
+} wfa_info_t;
+
+typedef struct wfa
+/*
+ *  Used to store all informations and data structures of a WFA
+ */
+{
+   wfa_info_t	*wfainfo;		/* misc. information about the WFA */
+   frame_type_e frame_type;		/* intra, predicted, bi-directional */
+   unsigned	states;			/* number of states */
+   unsigned	basis_states;		/* number of states in the basis */
+   unsigned	root_state;		/* root of the tree */
+   real_t	*final_distribution;    /* one pixel images */
+   byte_t	*level_of_state;	/* level of the image part which is
+					   represented by the current state */
+   byte_t	*domain_type;		/* Bit_0==1: auxilliary state
+					   Bit_1==1: used for Y compr */
+   mv_t		(*mv_tree)[MAXLABELS];	/* motion vectors */
+   word_t	(*tree)[MAXLABELS];	/* bintree partitioning */
+   u_word_t	(*x)[MAXLABELS];	/* range coordinate */
+   u_word_t	(*y)[MAXLABELS];	/* range coordinate */
+   word_t	(*into)[MAXLABELS][MAXEDGES + 1];   /* domain references */
+   real_t	(*weight)[MAXLABELS][MAXEDGES + 1]; /* lin.comb. coefficients */
+   word_t	(*int_weight)[MAXLABELS][MAXEDGES + 1]; /* bin. representation */
+   word_t	(*y_state)[MAXLABELS];	/* bintree of Y component */
+   byte_t	(*y_column)[MAXLABELS];	/* array for Y component references */
+   byte_t	(*prediction)[MAXLABELS]; /* DC prediction */
+   bool_t	(*delta_state);		/* delta state */
+} wfa_t;
+
+#endif /* not _WFA_H */
+
diff --git a/converter/other/fiasco/codec/wfalib.c b/converter/other/fiasco/codec/wfalib.c
new file mode 100644
index 00000000..a3acb975
--- /dev/null
+++ b/converter/other/fiasco/codec/wfalib.c
@@ -0,0 +1,774 @@
+/*
+ *  wfalib.c:		Library functions both for encoding and decoding
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/18 15:57:28 $
+ *  $Author: hafner $
+ *  $Revision: 5.5 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include <string.h>
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "misc.h"
+#include "wfalib.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static unsigned
+xy_to_address (unsigned x, unsigned y, unsigned level, unsigned n);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+wfa_t *
+alloc_wfa (bool_t coding)
+/*
+ *  WFA constructor:
+ *  Initialize the WFA structure 'wfa' and allocate memory.
+ *  Flag 'coding' indicates whether WFA is used for coding or decoding.
+ *
+ *  Return value:
+ *	pointer to the new WFA structure
+ */
+{
+   wfa_t *wfa = Calloc (1, sizeof (wfa_t));
+		 
+   /*
+    *  Allocate memory
+    */
+   wfa->final_distribution = Calloc (MAXSTATES, sizeof (real_t));
+   wfa->level_of_state     = Calloc (MAXSTATES, sizeof (byte_t));
+   wfa->domain_type        = Calloc (MAXSTATES, sizeof (byte_t));
+   wfa->delta_state        = Calloc (MAXSTATES, sizeof (bool_t));
+   wfa->tree               = Calloc (MAXSTATES * MAXLABELS, sizeof (word_t));
+   wfa->x                  = Calloc (MAXSTATES * MAXLABELS, sizeof (word_t));
+   wfa->y                  = Calloc (MAXSTATES * MAXLABELS, sizeof (word_t));
+   wfa->mv_tree            = Calloc (MAXSTATES * MAXLABELS, sizeof (mv_t));
+   wfa->y_state            = Calloc (MAXSTATES * MAXLABELS, sizeof (word_t));
+   wfa->into               = Calloc (MAXSTATES * MAXLABELS * (MAXEDGES + 1),
+				     sizeof (word_t));
+   wfa->weight             = Calloc (MAXSTATES * MAXLABELS * (MAXEDGES + 1),
+				     sizeof (real_t));
+   wfa->int_weight         = Calloc (MAXSTATES * MAXLABELS * (MAXEDGES + 1),
+				     sizeof (word_t));
+   wfa->wfainfo            = Calloc (1, sizeof (wfa_info_t));;
+   wfa->prediction         = Calloc (MAXSTATES * MAXLABELS, sizeof (byte_t));
+
+   wfa->wfainfo->wfa_name   = NULL;
+   wfa->wfainfo->basis_name = NULL;
+   wfa->wfainfo->title 	    = strdup ("");
+   wfa->wfainfo->comment    = strdup ("");
+
+   /*
+    *  Initialize structure
+    */
+   {
+      unsigned  state, label;
+
+      wfa->states       = 0;
+      wfa->basis_states = 0;
+      wfa->root_state   = 0;
+      for (state = 0; state < MAXSTATES; state++) 
+      {
+	 wfa->final_distribution [state] = 0;
+	 wfa->domain_type [state]        = 0;
+	 for (label = 0; label < MAXLABELS; label++)
+	 {
+	    wfa->into [state][label][0] = NO_EDGE;
+	    wfa->tree [state][label]    = RANGE;
+	    wfa->y_state [state][label] = RANGE;
+	 }
+      }
+   }
+
+   if (coding)				/* initialize additional variables */
+      wfa->y_column = Calloc (MAXSTATES * MAXLABELS, sizeof (byte_t));
+   else
+      wfa->y_column = NULL;
+   
+   return wfa;
+}
+
+void
+free_wfa (wfa_t *wfa)
+/*
+ *  WFA destructor:
+ *  Free memory of given 'wfa'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa' struct is discarded.
+ */
+{
+   if (wfa->wfainfo->wfa_name)
+      Free (wfa->wfainfo->wfa_name);
+   if (wfa->wfainfo->basis_name)
+      Free (wfa->wfainfo->basis_name);
+   if (wfa->wfainfo->title)
+      Free (wfa->wfainfo->title);
+   if (wfa->wfainfo->comment)
+      Free (wfa->wfainfo->comment);
+
+   Free (wfa->final_distribution);
+   Free (wfa->level_of_state);
+   Free (wfa->domain_type);
+   Free (wfa->tree);
+   Free (wfa->x);
+   Free (wfa->y);
+   Free (wfa->mv_tree);
+   Free (wfa->y_state);
+   Free (wfa->into);
+   Free (wfa->weight);
+   Free (wfa->int_weight);
+   Free (wfa->wfainfo);
+   Free (wfa->prediction);
+   Free (wfa->delta_state);
+   if (wfa->y_column)
+      Free (wfa->y_column);
+   Free (wfa);
+}
+
+real_t 
+compute_final_distribution (unsigned state, const wfa_t *wfa)
+/*
+ *  Compute the final distribution of the given 'state'.
+ *  Uses the fact that the generated 'wfa' is average preserving.
+ *
+ *  Return value:
+ *	final distribution
+ */
+{
+   unsigned label;
+   real_t   final = 0;
+
+   for (label = 0; label < MAXLABELS; label++)
+   {
+      unsigned edge;
+      int      domain;
+      
+      if (ischild (domain = wfa->tree [state][label]))
+	 final += wfa->final_distribution [domain];
+      for (edge = 0; isedge (domain = wfa->into [state][label][edge]); edge++)
+	 final += wfa->weight [state][label][edge]
+		  * wfa->final_distribution [domain];
+   }
+   
+   return final / MAXLABELS;
+}
+
+word_t *
+compute_hits (unsigned from, unsigned to, unsigned n, const wfa_t *wfa)
+/*
+ *  Selects the 'n' most popular domain images of the given 'wfa'.
+ *  Consider only linear combinations of state images
+ *  {i | 'from' <= i <= 'to'}. I.e. domains are in {i | from <= i < 'to'}
+ *  Always ensure that state 0 is among selected states even though from
+ *  may be > 0.
+ *  
+ *  Return value:
+ *	pointer to array of the most popular state images
+ *	sorted by increasing state numbers and terminated by -1
+ */
+{
+   word_t   *domains;
+   unsigned  state, label, edge;
+   int       domain;
+   pair_t   *hits = Calloc (to, sizeof (pair_t));
+
+   for (domain = 0; domain < (int) to; domain++)
+   {
+      hits [domain].value = domain;
+      hits [domain].key   = 0;
+   }
+   
+   for (state = from; state <= to; state++)
+      for (label = 0; label < MAXLABELS; label++)
+	 for (edge = 0; isedge (domain = wfa->into [state][label][edge]);
+	      edge++)
+	    hits [domain].key++;
+
+   qsort (hits + 1, to - 1, sizeof (pair_t), sort_desc_pair);
+
+   n       = min (to, n);
+   domains = Calloc (n + 1, sizeof (word_t));
+
+   for (domain = 0; domain < (int) n && (!domain || hits [domain].key);
+	domain++)
+      domains [domain] = hits [domain].value;
+   if (n != domain)
+      debug_message ("Only %d domains have been used in the luminance.",
+		     domain);
+   n = domain;
+   qsort (domains, n, sizeof (word_t), sort_asc_word);
+   domains [n] = -1;
+   
+   Free (hits);
+   
+   return domains;
+}
+
+void
+append_edge (unsigned from, unsigned into, real_t weight,
+	     unsigned label, wfa_t *wfa)
+/*
+ *  Append an edge from state 'from' to state 'into' with
+ *  the given 'label' and 'weight' to the 'wfa'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa' structure is changed.
+ */
+{
+   unsigned new;			/* position of the new edge */
+   unsigned edge;
+
+   /*
+    *  First look where to insert the new edge:
+    *  edges are sorted by increasing 'into' values
+    */
+   for (new = 0; (isedge (wfa->into [from][label][new])
+		  && wfa->into [from][label][new] < (int) into); new++)
+      ;
+   /*
+    *  Move the edges 'n' to position 'n+1', for n = max, ..., 'new'
+    */
+   for (edge = new; isedge (wfa->into [from][label][edge]); edge++)
+      ;
+   for (edge++; edge != new; edge--)
+   {
+      wfa->into [from][label][edge]    = wfa->into [from][label][edge - 1];
+      wfa->weight [from][label][edge]  = wfa->weight [from][label][edge - 1];
+      wfa->int_weight [from][label][edge]
+	 = wfa->int_weight [from][label][edge - 1];
+   }
+   /*
+    *  Insert the new edge
+    */
+   wfa->into [from][label][edge]       = into;
+   wfa->weight [from][label][edge]     = weight;
+   wfa->int_weight [from][label][edge] = weight * 512 + 0.5;
+}
+
+void 
+remove_states (unsigned from, wfa_t *wfa)
+/* 
+ *  Remove 'wfa' states 'wfa->basis_states',...,'wfa->states' - 1.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa' structure is cleared for the given states.
+ */
+{
+   unsigned state;
+
+   for (state = from; state < wfa->states; state++)
+   {
+      unsigned label;
+      
+      for (label = 0; label < MAXLABELS; label++) 
+      {
+	 wfa->into [state][label][0]      = NO_EDGE;
+	 wfa->tree [state][label]         = RANGE;
+	 wfa->prediction [state][label]   = FALSE;
+	 wfa->y_state [state][label]      = RANGE;
+	 wfa->mv_tree [state][label].type = NONE;
+	 wfa->mv_tree [state][label].fx   = 0;
+	 wfa->mv_tree [state][label].fy   = 0;
+	 wfa->mv_tree [state][label].bx   = 0;
+	 wfa->mv_tree [state][label].by   = 0;
+      }
+      wfa->domain_type [state] = 0;
+      wfa->delta_state [state] = FALSE;
+   }
+
+   wfa->states = from;
+}
+
+void
+copy_wfa (wfa_t *dst, const wfa_t *src)
+/*
+ *  Copy WFA struct 'src' to WFA struct 'dst'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'dst' is filled with same data as 'src'
+ *
+ *  NOTE: size of WFA 'dst' must be at least size of WFA 'src'
+ */
+{
+   unsigned state;
+
+   memset (dst->final_distribution, 0, MAXSTATES * sizeof (real_t));
+   memset (dst->level_of_state, 0, MAXSTATES * sizeof (byte_t));
+   memset (dst->domain_type, 0, MAXSTATES * sizeof (byte_t));
+   memset (dst->mv_tree, 0, MAXSTATES * MAXLABELS * sizeof (mv_t));
+   memset (dst->tree, 0, MAXSTATES * MAXLABELS * sizeof (word_t));
+   memset (dst->x, 0, MAXSTATES * MAXLABELS * sizeof (word_t));
+   memset (dst->y, 0, MAXSTATES * MAXLABELS * sizeof (word_t));
+   memset (dst->y_state, 0, MAXSTATES * MAXLABELS * sizeof (word_t));
+   memset (dst->into, NO_EDGE,
+	   MAXSTATES * MAXLABELS * (MAXEDGES + 1) * sizeof (word_t));
+   memset (dst->weight, 0,
+	   MAXSTATES * MAXLABELS * (MAXEDGES + 1) * sizeof (real_t));
+   memset (dst->int_weight, 0,
+	   MAXSTATES * MAXLABELS * (MAXEDGES + 1) * sizeof (word_t));
+   memset (dst->prediction, 0, MAXSTATES * MAXLABELS * sizeof (byte_t));
+   memset (dst->delta_state, 0, MAXSTATES * sizeof (bool_t));
+   if (dst->y_column)
+      memset (dst->y_column, 0, MAXSTATES * MAXLABELS * sizeof (byte_t));
+
+   for (state = 0; state < MAXSTATES; state++) /* clear WFA struct */
+   {
+      unsigned label;
+      
+      for (label = 0; label < MAXLABELS; label++)
+      {
+	 dst->into [state][label][0]      = NO_EDGE;
+	 dst->tree [state][label]         = RANGE;
+	 dst->mv_tree [state][label].type = NONE;
+	 dst->y_state[state][label]       = RANGE;
+      }
+      dst->delta_state [state] = NO;
+      dst->domain_type [state] = 0;
+   }
+   
+   dst->frame_type   = src->frame_type;
+   dst->states 	     = src->states;
+   dst->basis_states = src->basis_states;
+   dst->root_state   = src->root_state;
+
+   memcpy (dst->wfainfo, src->wfainfo, sizeof (wfa_info_t));
+
+   if (dst->states == 0)		/* nothing to do */
+      return;
+
+   memcpy (dst->final_distribution, src->final_distribution,
+	   src->states * sizeof (real_t));
+   memcpy (dst->level_of_state, src->level_of_state,
+	   src->states * sizeof (byte_t));
+   memcpy (dst->domain_type, src->domain_type,
+	   src->states * sizeof (byte_t));
+   memcpy (dst->delta_state, src->delta_state,
+	   src->states * sizeof (bool_t));
+   memcpy (dst->mv_tree, src->mv_tree,
+	   src->states * MAXLABELS * sizeof (mv_t));
+   memcpy (dst->tree, src->tree,
+	   src->states * MAXLABELS * sizeof (word_t));
+   memcpy (dst->x, src->x,
+	   src->states * MAXLABELS * sizeof (word_t));
+   memcpy (dst->y, src->y,
+	   src->states * MAXLABELS * sizeof (word_t));
+   memcpy (dst->y_state, src->y_state,
+	   src->states * MAXLABELS * sizeof (word_t));
+   memcpy (dst->into, src->into,
+	   src->states * MAXLABELS * (MAXEDGES + 1) * sizeof (word_t));
+   memcpy (dst->weight, src->weight,
+	   src->states * MAXLABELS * (MAXEDGES + 1) * sizeof (real_t));
+   memcpy (dst->int_weight, src->int_weight,
+	   src->states * MAXLABELS * (MAXEDGES + 1) * sizeof (word_t));
+   memcpy (dst->prediction, src->prediction,
+	   src->states * MAXLABELS * sizeof (byte_t));
+   if (dst->y_column)
+      memcpy (dst->y_column, src->y_column,
+	      src->states * MAXLABELS * sizeof (byte_t));
+}
+
+void
+locate_subimage (unsigned orig_level, unsigned level, unsigned bintree,
+		 unsigned *x, unsigned *y, unsigned *width, unsigned *height)
+/*
+ *  Compute pixel coordinates of the subimage which 'bintree' address is given.
+ *  The level of the original image is 'orig_level' and the level of the
+ *  subimage is 'level'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'*x', '*y'		coordinates of the upper left corner
+ *      '*width', '*height'	size of image
+ */
+{
+   /*
+    *  Compute coordinates of the subimage
+    */
+   *x = *y = 0;				/* start at NW corner */
+   *width  = width_of_level (level);
+   *height = height_of_level (level);
+
+   if (level > orig_level)
+   {
+      error ("size of tile must be less or equal than image size.");
+      return;
+   }
+   else if (bintree >= (unsigned) (1 << (orig_level - level)))
+   {
+      error ("address out of bounds.");
+      return;
+   }
+   else if (level < orig_level)
+   {
+      unsigned mask;			/* mask for bintree -> xy conversion */
+      bool_t   hor;			/* 1 next subdivision is horizontal
+					   0 next subdivision is vertical */
+      unsigned l = orig_level - 1;	/* current level */
+      
+      hor = orig_level % 2;		/* start with vertival subdivision
+					   for square image and vice versa */
+   
+      for (mask = 1 << (orig_level - level - 1); mask; mask >>= 1, hor = !hor)
+      {
+	 if (bintree & mask)		/* change coordinates */
+	 {
+	    if (hor)			/* horizontal subdivision */
+	       *y += height_of_level (l);
+	    else			/* vertical subdivision */
+	       *x += width_of_level (l);
+	 }
+	 l--;
+      }
+   }
+}
+
+void
+compute_spiral (int *vorder, unsigned image_width, unsigned image_height,
+		unsigned tiling_exp, bool_t inc_spiral)
+/*
+ *  Compute image tiling with spiral order.
+ *  'inc_spiral' specifies whether the spiral starts in the middle
+ *  of the image (TRUE) or at the border (FALSE).
+ *  'image_width'x'image_height' define the size of the image.
+ *  The image is split into 'tiling->exp' tiles.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	vorder[] is filled with tiling permutation
+ */
+{
+   unsigned x, y;			/* current position */
+   unsigned xmin, xmax, ymin, ymax;	/* boundaries for current line */
+   unsigned width, height;		/* offset for each tile */
+   unsigned lx, ly, level;		/* level x and y */
+   unsigned tiles;			/* total number of tiles */
+   unsigned address;			/* bintree address */
+   
+   lx     = log2 (image_width - 1) + 1;
+   ly     = log2 (image_height - 1) + 1;
+   level  = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0);
+   tiles  = 1 << tiling_exp;		/* Number of image tiles */
+   width  = width_of_level (level - tiling_exp);
+   height = height_of_level (level - tiling_exp);
+   for (address = 0; address < tiles; address++)
+   {
+      unsigned x0, y0, width, height;
+      
+      locate_subimage (level, level - tiling_exp, address,
+		       &x0, &y0, &width, &height);
+      vorder [address] = (x0 < image_width && y0 < image_height) ? 0 : -1;
+   }
+
+   xmin    = 0;
+   xmax    = width_of_level (level);
+   ymin    = 0;
+   ymax    = height_of_level (level);
+   address = 0;
+
+   /*
+    *  1234
+    *  CDE5  Traverse image in spiral order 
+    *  BGF6  starting at the top left corner
+    *  A987
+    */
+   while (TRUE)
+   {
+      for (x = xmin, y = ymin; x < xmax; x += width) /* W>E */
+      {
+	 while (vorder [address] == -1)
+	    address++;
+	 if (x < image_width && y < image_height) /* valid range */
+	    vorder [address++] = xy_to_address (x, y, level, tiling_exp);
+	 while (address < tiles && vorder [address] == -1)
+	    address++;
+      }
+      ymin += height;
+
+      if (address >= tiles)
+	 break;
+      
+      for (x = xmax - width, y = ymin; y < ymax; y += height) /* N>S  */
+      {
+	 while (vorder [address] == -1)
+	    address++;
+	 if (x <= image_width && y <= image_height) /* valid range */
+	    vorder [address++] = xy_to_address (x, y, level, tiling_exp);
+	 while (address < tiles && vorder [address] == -1)
+	    address++;
+      }
+      xmax -= width;
+
+      if (address >= tiles)
+	 break;
+
+      for (x = xmax - width, y = ymax - width; x >= xmin; x -= width) /* E<W */
+      {
+	 while (vorder [address] == -1)
+	    address++;
+	 if (x <= image_width && y <= image_height) /* valid range */
+	    vorder [address++] = xy_to_address (x, y, level, tiling_exp);
+	 while (address < tiles && vorder [address] == -1)
+	    address++;
+      }
+      ymax -= height;
+
+      if (address >= tiles)
+	 break;
+
+      for (x = xmin, y = ymax - height; y >= ymin; y -= height)	/* S>N */
+      {
+	 while (vorder [address] == -1)
+	    address++;
+	 if (x <= image_width && y <= image_height) /* valid range */
+	    vorder [address++] = xy_to_address (x, y, level, tiling_exp);
+	 while (address < tiles && vorder [address] == -1)
+	    address++;
+      }
+      xmin += width;
+	 
+      if (address >= tiles)
+	 break;
+   }
+
+   if (inc_spiral)
+   {
+      int i = 0, j = tiles - 1;
+
+      while (i < j)
+      {
+	 int tmp;
+	    
+	 while (vorder [i] == -1)
+	    i++;
+	 while (vorder [j] == -1)
+	    j--;
+	    
+	 tmp 	       = vorder [i];
+	 vorder [i] = vorder [j];
+	 vorder [j] = tmp;
+	 i++;
+	 j--;
+      }
+   }
+   /*
+    *  Print tiling info
+    */
+   {
+      unsigned number;
+      
+      for (number = 0, address = 0; address < tiles; address++)
+	 if (vorder [address] != -1)
+	    debug_message ("number %d: address %d",
+			   number++, vorder [address]);
+   }
+}
+
+bool_t
+find_range (unsigned x, unsigned y, unsigned band,
+	    const wfa_t *wfa, unsigned *range_state, unsigned *range_label)
+/*
+ *  Find a range ('*range_state', '*range_label') that contains
+ *  pixel ('x', 'y') in the iven color 'band'.
+ *
+ *  Return value:
+ *	TRUE on success, or FALSE if there is no such range
+ *
+ *  Side effects:
+ *	'*range_state' and '*range_label' are modified on success.
+ */
+{
+   unsigned state, label;
+   unsigned first_state, last_state;
+   bool_t   success = NO;
+   
+   first_state = wfa->basis_states;
+   last_state  = wfa->states;
+   if (wfa->wfainfo->color)
+      switch (band)
+      {
+	 case Y:
+	    first_state = wfa->basis_states;
+	    last_state  = wfa->tree [wfa->tree [wfa->root_state][0]][0];
+	    break;
+	 case Cb:
+	    first_state = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1;
+	    last_state  = wfa->tree [wfa->tree [wfa->root_state][0]][1];
+	    break;
+	 case Cr:
+	    first_state = wfa->tree [wfa->tree [wfa->root_state][0]][1] + 1;
+	    last_state  = wfa->states;
+	    break;
+	 default:
+	    error ("unknown color component.");
+      }
+
+   for (state = first_state; state < last_state; state++)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (isrange (wfa->tree [state][label]))
+	    if (x >= wfa->x [state][label] && y >= wfa->y [state][label]
+		&& x < (unsigned) (wfa->x [state][label]
+			+ width_of_level (wfa->level_of_state [state] - 1))
+		&& y < (unsigned) (wfa->y [state][label]
+			+ height_of_level (wfa->level_of_state [state] - 1))) 
+	    {
+	       success      = YES;
+	       *range_state = state;
+	       *range_label = label;
+
+	       return success;
+	    }
+
+   return success;
+}
+
+void
+sort_ranges (unsigned state, unsigned *domain,
+	     range_sort_t *rs, const wfa_t *wfa)
+/*
+ *  Generate list of ranges in coder order.
+ *  'state' is the current state of the call tree while 'domain' is the
+ *  index of the last added WFA state.
+ *
+ *  Side effects:
+ *	'domain' is incremented after recursion returns
+ *	'rs'	 is filled accordingly
+ *
+ *  No return value.
+ */
+{
+   unsigned label;
+   
+   for (label = 0; label < MAXLABELS; label++)
+   {
+      if (isrange (wfa->tree [state][label]))
+	 rs->range_subdivided [rs->range_no] = NO;
+      else
+      {
+	 sort_ranges (wfa->tree [state][label], domain, rs, wfa);
+	 rs->range_subdivided [rs->range_no] = YES;
+      }
+
+      rs->range_state [rs->range_no]      = state;
+      rs->range_label [rs->range_no]      = label;
+      rs->range_max_domain [rs->range_no] = *domain;
+      while (!usedomain (rs->range_max_domain [rs->range_no], wfa))
+	 rs->range_max_domain [rs->range_no]--;
+
+      if (label == 1 || !rs->range_subdivided [rs->range_no])
+	 rs->range_no++;
+   }
+   
+   (*domain)++;
+}
+
+bool_t
+locate_delta_images (wfa_t *wfa)
+/*
+ *  Locate all WFA states that are part of a delta approximation.
+ *  I.e., these states are assigned to ranges that have been predicted
+ *  via MC or ND.
+ *
+ *  Return value:
+ *	TRUE	at least one state is part of a delta approximation
+ *	FALSE	no delta approximations in this WFA
+ *
+ *  Side effects:
+ *	'wfa->delta [state][label]' is set accordingly.
+ */
+{
+   unsigned state, label;
+   bool_t   delta = NO;
+
+   for (state = wfa->root_state; state >= wfa->basis_states; state--)
+      wfa->delta_state [state] = NO;
+
+   for (state = wfa->root_state; state >= wfa->basis_states; state--)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (ischild (wfa->tree [state][label]))
+	    if (wfa->mv_tree [state][label].type != NONE
+		|| isedge (wfa->into [state][label][0])
+		|| wfa->delta_state [state])
+	    {
+	       delta = YES;
+	       wfa->delta_state [wfa->tree [state][label]] = YES;
+	    }
+
+   return delta;
+}
+
+/*****************************************************************************
+
+				private code
+  
+******************************************************************************/
+
+static unsigned
+xy_to_address (unsigned x, unsigned y, unsigned level, unsigned n)
+/*
+ *  Compute bintree address of subimage at coordinates ('x', 'y').
+ *  Size of original image is determined by 'level'.
+ *  'n' specifies number of iterations.
+ *
+ *  Return value:
+ *	address of subimage
+ */ 
+{ 
+   unsigned address = 0;
+
+   while (n--)
+   {
+      address <<= 1;
+      if (--level % 2) 
+      {
+	 if (x & width_of_level (level))
+	    address++;
+      }
+      else
+      {
+	 if (y & height_of_level (level))
+	    address++;
+      }
+   }
+   
+   return address;
+}
diff --git a/converter/other/fiasco/codec/wfalib.h b/converter/other/fiasco/codec/wfalib.h
new file mode 100644
index 00000000..4622fcd2
--- /dev/null
+++ b/converter/other/fiasco/codec/wfalib.h
@@ -0,0 +1,66 @@
+/*
+ *  wfalib.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _WFALIB_H
+#define _WFALIB_H
+
+#include "types.h"
+#include "wfa.h"
+#include "list.h"
+
+typedef struct range_sort
+{
+   u_word_t *range_state;
+   byte_t   *range_label;
+   u_word_t *range_max_domain;
+   bool_t   *range_subdivided;
+   unsigned  range_no;
+} range_sort_t;
+
+bool_t
+locate_delta_images (wfa_t *wfa);
+void
+sort_ranges (unsigned state, unsigned *domain,
+	     range_sort_t *rs, const wfa_t *wfa);
+bool_t
+find_range (unsigned x, unsigned y, unsigned band,
+	    const wfa_t *wfa, unsigned *range_state, unsigned *range_label);
+void
+compute_spiral (int *vorder, unsigned image_width, unsigned image_height,
+		unsigned tiling_exp, bool_t inc_spiral);
+void
+locate_subimage (unsigned orig_level, unsigned level, unsigned bintree,
+		 unsigned *x, unsigned *y, unsigned *width, unsigned *height);
+void
+copy_wfa (wfa_t *dst, const wfa_t *src);
+void 
+remove_states (unsigned from, wfa_t *wfa);
+void
+append_edge (unsigned from, unsigned into, real_t weight,
+	     unsigned label, wfa_t *wfa);
+word_t *
+compute_hits (unsigned from, unsigned to, unsigned n, const wfa_t *wfa);
+real_t 
+compute_final_distribution (unsigned state, const wfa_t *wfa);
+wfa_t *
+alloc_wfa (bool_t coding);
+void
+free_wfa (wfa_t *wfa);
+bool_t
+locate_delta_images (wfa_t *wfa);
+
+#endif /* not _WFALIB_H */
+
diff --git a/converter/other/fiasco/config.h b/converter/other/fiasco/config.h
new file mode 100644
index 00000000..d6b15a84
--- /dev/null
+++ b/converter/other/fiasco/config.h
@@ -0,0 +1,96 @@
+/* config.h.  Generated automatically by configure.  */
+/* But then manually maintained as part of Netpbm! */
+
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if the X Window System is missing or not being used.  */
+#define X_DISPLAY_MISSING 1
+
+/* Define if shifting of signed integers works */
+#define HAVE_SIGNED_SHIFT 1
+
+/* Define if you don't have the CLOCKS_PER_SEC define in <time.h>. */
+/* #undef CLOCKS_PER_SEC */
+
+/* The number of bytes in a char.  */
+#define SIZEOF_CHAR 1
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* Define if you have the log2 function.  */
+/* #undef HAVE_LOG2 */
+/* For Netpbm, we won't use log2() because it might not exist.  In
+   Netpbm, misc.c contains Log2(), so we just define log2 as Log2 here.
+   But first, we include <math.h> because if we don't it may get included
+   after config.h, and then there could be a redefinition issue with log2.
+*/
+#include <math.h>
+#undef log2
+#define log2 Log2
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the strcasecmp function.  */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strdup function.  */
+#define HAVE_STRDUP 1
+
+/* Define if you have the <X11/extensions/XShm.h> header file.  */
+/* #undef HAVE_X11_EXTENSIONS_XSHM_H */
+
+/* Define if you have the <assert.h> header file.  */
+#define HAVE_ASSERT_H 1
+
+/* Define if you have the <features.h> header file.  */
+#define HAVE_FEATURES_H 1
+
+/* Define if you have the <setjmp.h> header file.  */
+#define HAVE_SETJMP_H 1
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/time.h> header file.  */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the m library (-lm).  */
+#define HAVE_LIBM 1
+
+/* Name of package */
+#define PACKAGE "fiasco"
+
+/* Version number of package */
+#define VERSION "1.0"
+
+#define FIASCO_SHARE "/etc/"
diff --git a/converter/other/fiasco/display.c b/converter/other/fiasco/display.c
new file mode 100644
index 00000000..9e531149
--- /dev/null
+++ b/converter/other/fiasco/display.c
@@ -0,0 +1,422 @@
+/*
+ *  display.c:		X11 display of frames
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ *		
+ *  Based on mpeg2decode, (C) 1994, MPEG Software Simulation Group
+ *  and      mpeg2play,   (C) 1994 Stefan Eckart
+ *                                 <stefan@lis.e-technik.tu-muenchen.de>
+ *  and      tmndec       (C) 1995, 1996  Telenor R&D, Norway
+ */
+
+/*
+ *  $Date: 2000/07/03 19:35:59 $
+ *  $Author: hafner $
+ *  $Revision: 5.2 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#ifndef X_DISPLAY_MISSING
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#	include <string.h>
+#else /* not STDC_HEADERS */
+#	if HAVE_STRING_H
+#		include <string.h>
+#	else /* not HAVE_STRING_H */
+#		include <strings.h>
+#	endif /* not HAVE_STRING_H */
+#endif /* not STDC_HEADERS */
+
+#include "types.h"
+#include "macros.h"
+#include "display.h"
+#include "binerror.h"
+
+/*****************************************************************************
+
+	       shared memory functions (if USE_SHM is defined)
+  
+*****************************************************************************/
+
+#ifdef USE_SHM
+
+#ifdef HAVE_FEATURES_H
+#include <features.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+
+int
+XShmQueryExtension (Display *dpy);
+int
+XShmGetEventBase (Display *dpy);
+
+static int
+HandleXError (Display *dpy, XErrorEvent *event);
+static void
+InstallXErrorHandler (x11_info_t *xinfo);
+static void
+DeInstallXErrorHandler (x11_info_t *xinfo);
+
+static int		shmem_flag;
+static XShmSegmentInfo	shminfo1, shminfo2;
+static int		gXErrorFlag;
+static int		CompletionType = -1;
+
+static int
+HandleXError (Display *dpy, XErrorEvent *event)
+{
+   gXErrorFlag = 1;
+   
+   return 0;
+}
+
+static void
+InstallXErrorHandler (x11_info_t *xinfo)
+{
+   XSetErrorHandler (HandleXError);
+   XFlush (xinfo->display);
+}
+
+static void
+DeInstallXErrorHandler (x11_info_t *xinfo)
+{
+   XSetErrorHandler (NULL);
+   XFlush (xinfo->display);
+}
+
+#endif /* USE_SHM */
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+display_image (unsigned x0, unsigned y0, x11_info_t *xinfo)
+/*
+ *  Display 'image' at pos ('x0', 'y0') in the current window
+ *  (given by 'xinfo->window'). 
+ *
+ *  No return value.
+ */
+{
+   int byte_order_check = 1;
+   
+   /*
+    *  Always work in native bit and byte order. This tells Xlib to
+    *  reverse bit and byte order if necessary when crossing a
+    *  network. Frankly, this part of XImages is somewhat
+    *  underdocumented, so this may not be exactly correct.
+    */
+   if (*(char *) & byte_order_check == 1)
+   {
+      xinfo->ximage->byte_order       = LSBFirst;
+      xinfo->ximage->bitmap_bit_order = LSBFirst;
+   }
+   else
+   {
+      xinfo->ximage->byte_order       = MSBFirst;
+      xinfo->ximage->bitmap_bit_order = MSBFirst;
+   }    
+
+   /* Display dithered image */
+#ifdef USE_SHM
+   if (shmem_flag)
+   {
+      XEvent xev;
+      
+      XShmPutImage (xinfo->display, xinfo->window, xinfo->gc, xinfo->ximage,
+		    0, 0, x0, y0, xinfo->ximage->width, xinfo->ximage->height,
+		    True);
+      XFlush (xinfo->display);
+      
+      while (!XCheckTypedEvent (xinfo->display, CompletionType, &xev))
+	 ;
+   }
+   else 
+#endif /* USE_SHM */
+   {
+      xinfo->ximage->data = (char *) xinfo->pixels; 
+      XPutImage (xinfo->display, xinfo->window, xinfo->gc, xinfo->ximage, 0, 0,
+		 x0, y0, xinfo->ximage->width, xinfo->ximage->height);
+   }
+}
+
+void
+close_window (x11_info_t *xinfo)
+{
+#ifdef USE_SHM
+   if (shmem_flag && xinfo->ximage)
+   {
+      XShmDetach (xinfo->display, &shminfo1);
+      XDestroyImage (xinfo->ximage);
+      xinfo->ximage = NULL;
+      shmdt (shminfo1.shmaddr);
+   }
+   else
+#endif /* USE_SHM */
+   if (xinfo->ximage)
+   {
+      XDestroyImage (xinfo->ximage);
+      xinfo->ximage = NULL;
+   }
+   if (xinfo->display)
+   {
+      XCloseDisplay (xinfo->display);
+      xinfo->display = NULL;
+   }
+}
+
+x11_info_t *
+open_window (const char *titlename, const char *iconname,
+	     unsigned width, unsigned height)
+/*
+ *  Open a X11 window of size 'width'x'height'.
+ *  If 'color' is false then allocate a colormap with grayscales.
+ *  Window and icon titles are given by 'titlename' and 'iconname',
+ *  respectively.
+ *
+ *  Return value:
+ *	X11 info struct containing display, gc, window ID and colormap.
+ */
+{
+   XVisualInfo		visual_template; /* template for XGetVisualInfo() */
+   XVisualInfo		visual_info;	/* return value of XGetVisualInfo() */
+   int			visual_n;	/* # of matches of XGetVisualInfo */
+   XEvent		xev;		
+   XSizeHints		hint;		
+   XSetWindowAttributes xswa;		
+   unsigned int		fg, bg;		/* foreground and background color */
+   unsigned int		mask;		/* event mask */
+   x11_info_t		*xinfo = calloc (1, sizeof (x11_info_t));
+   long                 visual_mask;
+   
+   if (!xinfo)
+      error ("Out of memory");
+   /*
+    *  Initialization of display
+    */
+   xinfo->display = XOpenDisplay (NULL);
+   if (xinfo->display == NULL)
+      error ("Can't open display.\n"
+	     "Make sure that your environment variable DISPLAY "
+	     "is set correctly.");
+
+   xinfo->screen = DefaultScreen (xinfo->display);
+   xinfo->gc     = DefaultGC (xinfo->display, xinfo->screen);
+
+   {
+      unsigned   depth [] 	= {32, 24, 16};
+      int        class [] 	= {TrueColor, PseudoColor};
+      const char *class_text [] = {"TrueColor", "PseudoColor"};
+      Status     found 		= 0;
+      unsigned   d, c;
+
+      for (d = 0; !found && d < sizeof (depth) / sizeof (unsigned); d++)
+	 for (c = 0; !found && c < sizeof (class) / sizeof (int); c++)
+	 {
+	    found = XMatchVisualInfo (xinfo->display, xinfo->screen,
+				      depth [d], class [c], &visual_info);
+	    if (found)
+	       fprintf (stderr, "%s : %d bit colordepth.\n",
+			class_text [c], depth [d]);
+	 }
+      if (!found && fiasco_get_verbosity ())
+	 error ("Can't find a 16/24/32 bit TrueColor/DirectColor display");
+   }
+   
+   /* Width and height of the display window */
+   hint.x = hint.y = 0;
+   hint.min_width  = hint.max_width  = hint.width  = width;
+   hint.min_height = hint.max_height = hint.height = height;
+   hint.flags = PSize | PMinSize | PMaxSize;
+
+   /* Get some colors */
+   bg = WhitePixel (xinfo->display, xinfo->screen);
+   fg = BlackPixel (xinfo->display, xinfo->screen);
+
+   /* Make the window */
+   mask = CWBackPixel | CWBorderPixel;
+   if (visual_info.depth >= 16)
+   {
+      mask |= CWColormap;
+      xswa.colormap = XCreateColormap (xinfo->display,
+				       DefaultRootWindow (xinfo->display),
+				       visual_info.visual, AllocNone);
+   }
+   xswa.background_pixel = bg;
+   xswa.border_pixel     = fg;
+   xinfo->window = XCreateWindow (xinfo->display,
+				  DefaultRootWindow (xinfo->display), 0, 0,
+				  width, height, 1, visual_info.depth,
+				  InputOutput, visual_info.visual,
+				  mask, &xswa);
+
+   XSelectInput (xinfo->display, xinfo->window, StructureNotifyMask);
+
+   /* Tell other applications about this window */
+   XSetStandardProperties (xinfo->display, xinfo->window, titlename, iconname,
+			   None, NULL, 0, &hint);
+
+   /* Map window. */
+   XMapWindow (xinfo->display, xinfo->window);
+
+   /* Wait for map. */
+   do
+   {
+      XNextEvent (xinfo->display, &xev);
+   }
+   while (xev.type != MapNotify || xev.xmap.event != xinfo->window);
+
+   /* Allocate colors */
+
+   return xinfo;
+}
+
+void
+alloc_ximage (x11_info_t *xinfo, unsigned width, unsigned height)
+/*
+ *  Allocate ximage of size 'width'x'height'.
+ *  If USE_SHM is defined then use shared memory extensions.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'ximage->ximage' and 'ximage->pixels' are set to useful values.
+ */
+{
+   char dummy;
+   
+#ifdef USE_SHM
+   if (XShmQueryExtension(xinfo->display))
+   {
+      if (fiasco_get_verbosity ())
+	 fprintf (stderr, "Trying shared memory.\n");
+      shmem_flag = 1;
+   }
+   else
+   {
+      shmem_flag = 0;
+      if (fiasco_get_verbosity ())
+	 fprintf (stderr,
+		  "Shared memory not supported\nReverting to normal Xlib.\n");
+   }
+
+   if (shmem_flag)
+      CompletionType = XShmGetEventBase (xinfo->display) + ShmCompletion;
+
+   InstallXErrorHandler (xinfo);
+
+   if (shmem_flag)
+   {
+      xinfo->ximage = XShmCreateImage (xinfo->display,
+				       DefaultVisual (xinfo->display,
+						      xinfo->screen),
+				       DefaultDepth (xinfo->display,
+						     xinfo->screen), ZPixmap,
+				       NULL, &shminfo1, width, height);
+
+      /* If no go, then revert to normal Xlib calls. */
+
+      if (xinfo->ximage == NULL)
+      {
+	 if (fiasco_get_verbosity ())
+	    fprintf (stderr,
+		     "Shared memory error, disabling (Ximage error).\n");
+	 goto shmemerror;
+      }
+
+      /* Success here, continue. */
+
+      shminfo1.shmid = shmget (IPC_PRIVATE, xinfo->ximage->bytes_per_line
+			       * xinfo->ximage->height, IPC_CREAT | 0777);
+
+      if (shminfo1.shmid < 0)
+      {
+	 XDestroyImage (xinfo->ximage);
+	 if (fiasco_get_verbosity ())
+	    fprintf (stderr,
+		     "Shared memory error, disabling (seg id error).\n");
+	 goto shmemerror;
+      }
+
+      shminfo1.shmaddr = (char *) shmat (shminfo1.shmid, 0, 0);
+      shminfo2.shmaddr = (char *) shmat (shminfo2.shmid, 0, 0);
+
+      if (shminfo1.shmaddr == ((char *) -1))
+      {
+	 XDestroyImage (xinfo->ximage);
+	 if (shminfo1.shmaddr != ((char *) -1))
+	    shmdt (shminfo1.shmaddr);
+	 if (fiasco_get_verbosity ())
+	    fprintf (stderr,
+		     "Shared memory error, disabling (address error).\n");
+	 goto shmemerror;
+      }
+
+      xinfo->ximage->data = shminfo1.shmaddr;
+      xinfo->pixels       = (byte_t *) xinfo->ximage->data;
+      shminfo1.readOnly   = False;
+
+      XShmAttach (xinfo->display, &shminfo1);
+      XSync (xinfo->display, False);
+
+      if (gXErrorFlag)
+      {
+	 /* Ultimate failure here. */
+	 XDestroyImage (xinfo->ximage);
+	 shmdt (shminfo1.shmaddr);
+	 if (fiasco_get_verbosity ())
+	    fprintf (stderr, "Shared memory error, disabling.\n");
+	 gXErrorFlag = 0;
+	 goto shmemerror;
+      }
+      else
+	 shmctl (shminfo1.shmid, IPC_RMID, 0);
+      if (fiasco_get_verbosity ())
+	 fprintf (stderr, "Sharing memory.\n");
+   }
+   else
+   {
+     shmemerror:
+      shmem_flag = 0;
+#endif /* USE_SHM */
+
+      xinfo->ximage = XCreateImage (xinfo->display,
+				    DefaultVisual (xinfo->display,
+						   xinfo->screen),
+				    DefaultDepth (xinfo->display,
+						  xinfo->screen),
+				    ZPixmap, 0, &dummy, width, height, 8, 0);
+      xinfo->pixels = calloc (width * height,
+			      xinfo->ximage->depth <= 8
+			      ? sizeof (byte_t)
+			      : (xinfo->ximage->depth <= 16
+				 ? sizeof (u_word_t) : sizeof (unsigned int)));
+      if (!xinfo->pixels)
+	 error ("Out of memory.");
+    
+#ifdef USE_SHM
+   }
+
+   DeInstallXErrorHandler (xinfo);
+#endif /* USE_SHM */
+}
+
+#endif /* not X_DISPLAY_MISSING */
diff --git a/converter/other/fiasco/display.h b/converter/other/fiasco/display.h
new file mode 100644
index 00000000..5f30b117
--- /dev/null
+++ b/converter/other/fiasco/display.h
@@ -0,0 +1,49 @@
+/*
+ *  display.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:51:17 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _DISPLAY_H
+#define _DISPLAY_H
+
+#ifndef X_DISPLAY_MISSING
+
+#include <X11/Xlib.h>
+
+#include "types.h"
+#include "image.h"
+
+typedef struct x11_info
+{
+   Display *display;
+   int	    screen;			/* default screen number */
+   Window   window;			
+   XImage  *ximage;
+   GC	    gc;
+   byte_t  *pixels;
+} x11_info_t;
+
+void
+display_image (unsigned x0, unsigned y0, x11_info_t *xinfo);
+void
+close_window (x11_info_t *xinfo);
+x11_info_t *
+open_window (const char *titlename, const char *iconname,
+	     unsigned width, unsigned height);
+void
+alloc_ximage (x11_info_t *xinfo, unsigned width, unsigned height);
+
+#endif /* X_DISPLAY_MISSING */
+
+#endif /* not _DISPLAY_H */
diff --git a/converter/other/fiasco/doc/README.LIB b/converter/other/fiasco/doc/README.LIB
new file mode 100644
index 00000000..4bf8c382
--- /dev/null
+++ b/converter/other/fiasco/doc/README.LIB
@@ -0,0 +1,51 @@
+---------------------------------------------------------------------------
+	 FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+		       Copyright (C) 1994-2000
+     Ullrich Hafner <hafner@bigfoot.de>, http://ulli.linuxave.net
+			     Version 1.0
+---------------------------------------------------------------------------
+
+FIASCO is an image and video compression system based on fractal
+coding which outperforms the well known JPEG and MPEG
+standards. FIASCO has been developed during my Ph.D. thesis "Low
+Bit-Rate Image and Video Coding with Weighted Finite Automata", Mensch
+& Buch Verlag, ISBN 3-89820-002-7.
+
+Some information about the FIASCO compression library:
+The library consists of the five "classes"
+
+	- fiasco_coder: used to encode a still image or a sequence of
+	  frames to a FIASCO stream, see fiasco_coder(3) or the file
+	  bin/cwfa.c for details.
+
+	- fiasco_decoder: used to decode the individual frames step by
+	  step, see fiasco_decoder(3) or the file bin/dwfa.c for
+	  details. 
+
+	- fiasco_image: internal representation of an decoded FIASCO
+	  image, see fiasco_image(3) or the file bin/dwfa.c for
+	  details. 
+
+	- fiasco_renderer: used to render the generated image object
+	  to one of the supported X11 output formats, see
+	  fiasco_render(3) or the files bin/dwfa.c or bin/pnmpsnr.c for
+	  details.
+
+	- fiasco_options: used to control various decoder and encoder
+	  options, see fiasco_options(3) or the files bin/cwfa.c,
+	  bin/dwfa.c or bin/pnmpsnr.c for details.
+
+
+Since the coder doesn't store any internal information, the only
+method of this class is the function fiasco_coder ().
+
+For all other classes, a new object is created with the
+fiasco_[object]_new () function, e.g., fiasco_decoder_new () creates a
+new fiasco_decoder_t object. Each object has to be deleted manually by
+calling the destructor fiasco_[object]_delete () (or by calling the
+method object->delete (object)). If you prefer C++ calls: every
+function of the type fiasco_[object]_[method] can be called via
+[object]->[method] ([object], args), too.
+
+Note: PLEASE use only functions, which are noted in the fiasco.h file
+(i.e., all functions and types with the prefix fiasco_)!
diff --git a/converter/other/fiasco/doc/fiasco_c_options.3 b/converter/other/fiasco/doc/fiasco_c_options.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_delete.3 b/converter/other/fiasco/doc/fiasco_c_options_delete.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_delete.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_new.3 b/converter/other/fiasco/doc/fiasco_c_options_new.3
new file mode 100644
index 00000000..52efb86c
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_new.3
@@ -0,0 +1,432 @@
+.\" $Id: fiasco_c_options_new.3,v 1.1 2000/10/28 17:35:06 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B fiasco_c_options_new, fiasco_c_options_delete,
+.B fiasco_c_options_set_progress_meter, fiasco_c_options_set_basisfile,
+.B fiasco_c_options_set_smoothing, fiasco_c_options_set_tiling, 
+.B fiasco_c_options_set_chroma_quality, fiasco_c_options_set_optimizations,
+.B fiasco_c_options_set_prediction, fiasco_c_options_set_video_param,
+.B fiasco_c_options_set_quantization, fiasco_c_options_set_frame_pattern
+.B fiasco_c_options_set_title, fiasco_c_options_set_comment
+\- define additional options of FIASCO coder and decoder 
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_c_options_t *"
+.fi
+.BI "fiasco_c_options_new"
+.fi
+.BI "   (void);"
+.sp
+.BI "void"
+.fi
+.BI "fiasco_c_options_delete"
+.fi
+.BI "   (fiasco_c_options_t * "options );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_basisfile"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    const char * "filename );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_chroma_quality"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    float "quality_factor ,
+.fi
+.BI "    unsigned "dictionary_size );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_comment"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    const char * "comment );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_frame_pattern"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    const char * "pattern );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_optimizations"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    unsigned "min_block_level ,
+.fi
+.BI "    unsigned "max_block_level ,
+.fi
+.BI "    unsigned "max_elements ,
+.fi
+.BI "    unsigned "dictionary_size ,
+.fi
+.BI "    unsigned "optimization_level );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_quantization"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    unsigned "mantissa ,
+.fi
+.BI "    fiasco_rpf_range_e "range ,
+.fi
+.BI "    unsigned "dc_mantissa ,
+.fi
+.BI "    fiasco_rpf_range_e "dc_range );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_prediction"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    int "intra_prediction ,
+.fi
+.BI "    unsigned "min_block_level ,
+.fi
+.BI "    unsigned "max_block_level );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_progress_meter"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    fiasco_progress_e "type );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_smoothing"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    unsigned "smoothing );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_tiling"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    fiasco_tiling_e "method ,
+.fi
+.BI "    unsigned "exponent );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_title"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    const char * "title );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_c_options_set_video_param"
+.fi
+.BI "   (fiasco_c_options_t * "options ,
+.fi
+.BI "    unsigned "frames_per_second ,
+.fi
+.BI "    int "half_pixel_prediction ,
+.fi
+.BI "    int "cross_B_search ,
+.fi
+.BI "    int "B_as_past_ref );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_c_options_new()\fP function allocates and initializes a
+FIASCO options object which is used to control additional compression
+ parameters.
+
+Conversely, the function \fBfiasco_c_options_delete()\fP discards the
+given FIASCO coder options object.
+
+Several member functions are available to modify the default behavior
+of the FIASCO coder.
+
+\fBfiasco_c_options_set_smoothing()\fP sets the
+\fIsmoothing\fP-percentage along partitioning borders when the image
+is regenerated; default is 70. This value is stored in the FIASCO file
+and is used as default smoothing percentage in the decoder.
+
+\fBfiasco_c_options_set_frame_pattern()\fP sets the type of inter frame
+compression which should be applied to individual frames of a video
+stream; default is "IPPPPPPPPP". 
+
+\fBfiasco_c_options_set_tiling()\fP sets \fImethod\fP and \fIexponent\fP
+of the image tiling algorithm which runs as initial step of the
+encoder; by default the image is subdivided into 16 tiles which
+are sorted by decreasing variance. 
+
+\fBfiasco_c_options_set_basisfile()\fP sets the \fIfilename\fP of
+the FIASCO initial basis (codebook of dictionary vectors); default is
+"small.fco". 
+
+\fBfiasco_c_options_set_chroma_quality()\fP sets the quality used when
+coding the chroma channels of a color image to the term "\fIquality\fP
+of luminance / \fIquality_factor\fP"; default is 2. Moreover, the size
+of the codebook is limited by \fIdictionary_size\fP; default is 40
+elements. 
+
+\fBfiasco_c_options_set_comment()\fP sets a \fIcomment\fP string to be
+stored in the FIASCO file; default is the empty string. 
+
+\fBfiasco_c_options_set_title()\fP sets a \fItitle\fP string to be
+stored in the FIASCO file; default is the empty string. 
+
+\fBfiasco_c_options_set_optimizations()\fP toggles various coding
+optimizations. E.g., the size of the dictionary (default is 10000),
+the subset of dictionary elements to use for an individual
+approximation (default is 5), the size of the image blocks to consider
+(4x4, ..., 64x64), and some additional low level
+optimizations (default level is 1). 
+
+\fBfiasco_c_options_set_prediction()\fP enables an additional intra
+block prediction by using a DC component approximation. By giving
+levels \fImin_block_level\fP and \fImax_block_level\fP the prediction
+can be limited to a small range of blocks only. By default, this
+method is disabled. 
+
+\fBfiasco_c_options_set_video_param()\fP defines the framerate (default
+is 25) and toggles whether to use half pixel precise motion
+compensated prediction (disabled by default), whether to determine
+motion vectors of interpolated prediction with the Cross-B-Search
+algorithm (disabled by default), and whether to allow B frames to be
+used for B frame predicion (disabled by default).
+
+\fBfiasco_c_options_set_quantization()\fP defines the quantization
+parameters of the approximation coefficients. By default the range of
+DC coefficients is [-1,+1] using a mantissa of 5 bits (and one sign
+bit). By default, all other coefficients are quantized with 3 mantissa
+bits in the interval [-1.5,+1.5].
+
+\fBfiasco_c_options_set_progress_meter()\fP sets the type of progress
+meter to be used during coding. By default, an RPM style progress bar
+using 50 hash marks (####) is used.
+
+.SH ARGUMENTS
+.TP
+options
+This object encapsulates various coding parameters.  
+
+.TP
+smoothing
+This percentage (range is 0 - i.e., no smoothing - to 100) defines how
+much the regenerated image is smoothed along the partitioning borders.
+
+.TP
+method
+Defines the algorithm which should be used to sort the image tiles
+which are generated in the initial coding step. If \fImethod\fP is
+\fBFIASCO_VARIANCE_ASC\fP then the tiles are sorted by variance - the
+first tile has the lowest variance. Conversely, when using
+\fBFIASCO_VARIANCE_DSC\fP the first tile has the largest variance. If
+\fImethod\fP is \fBFIASCO_SPIRAL_ASC\fP then the tiles are sorted like
+a spiral starting in the middle of the image. Conversely, when using
+\fBFIASCO_SPIRAL_DSC\fP the tiles are sorted like a spiral starting in
+the upper left corner.
+
+.TP
+exponent
+This value sets the number of image tiles - which are generated in the
+initial step of the encoder - to 2^\fIexponent\fP.
+
+.TP
+title
+This value is the title string of the FIASCO file. It is displayed, e.g.,
+in the window title of the decoder.
+
+.TP
+comment
+This value defines an optional comment to be stored in the FIASCO file.
+
+.TP
+pattern
+This string defines the sequence of frame types. Character \fIn\fP of
+the string defines the type of frame \fIn\fP (\fIpattern\fP is
+periodically extended). Three different frame types are available
+(case insensitive): choose 'i' for intra-frames (no inter frame
+prediction is used), 'p' for predicted frames (a frame of the
+past is used for prediction), or 'b' for bi-directional predicted
+frames (both a frame of the past and the future is used for
+prediction).
+
+.TP
+filename
+The initial basis (codebook) of the coder is loaded from this
+(ASCII) file. Files that already come with FIASCO are "small.fco" (3 elements),
+"medium.fco" (132 elements), and "large.fco" (219 elements). 
+
+.TP
+quality_factor
+When coding chroma channels (Cb and Cr band) the approximation quality
+is determined by the term `quality of Y component' / \fIquality_factor\fP.
+
+.TP
+dictionary_size
+FIASCO uses a dictionary (codebook) of variable size to approximate
+individual image blocks. The size of the codebook can be limited by
+\fIdictionary_size\fP to reduce the coding time, however, at the cost
+of decreasing quality. 
+
+.TP
+min_block_level
+During coding only those image blocks are considered for approximation
+(or prediction) which binary tree level is larger than
+\fImin_block_level\fP (minimum value is 3). (Since FIASCO internally
+works with binary trees, the size of an image block is determined by
+the \fIlevel\fP of the corresponding binary tree). Refer to following
+table to convert these values:
+
+.ce
+level | width | height
+.fi
+------+-------+--------
+.fi
+  0   |    1  |    1  
+.fi
+  1   |    1  |    2  
+.fi
+  2   |    2  |    2  
+.fi
+  3   |    2  |    4  
+.fi
+  4   |    4  |    4  
+.fi
+  5   |    4  |    8  
+.fi
+  6   |    8  |    8  
+.fi
+  7   |    8  |   16
+.fi
+------+-------+--------
+.fi
+The larger this value is the faster the coder runs but the worse the
+image quality will be.
+
+.TP
+max_block_level
+During coding only those image blocks are considered for approximation
+(or prediction) which binary tree level is smaller than
+\fImax_block_level\fP. The smaller this value is the faster the coder
+runs but the worse the image quality will be.
+
+.TP
+max_elements
+This value defines how many dictionary elements can be
+used to approximate an individual image block. The smaller this positive
+value (range is 1 to 5) is the faster the coder runs but the worse the
+image quality will be. 
+
+.TP
+optimization_level
+Additional low level optimizations are available by setting
+\fIoptimization_level\fP to one of the following values:
+.fi
+0 standard approximation method
+.fi
+1 slightly increases the approximation quality, running time is
+twice as high as with the standard method 
+.fi
+2 hardly increases the approximation quality of method 1, running time
+is twice as high as with method 1 (this method just remains for
+completeness) 
+.fi
+
+.TP
+intra_prediction
+If \fIintra_prediction\fP is set to a non-zero value then an
+additional block prediction of intra-frames is enabled. For some
+images, the image quality is slightly improved, however, at the cost of
+a significantly increased running time of the coder. 
+
+.TP
+frames_per_second
+This value defines the frame rate, i.e., how many frames per second
+should be displayed. This value has no effect during coding, it is just
+passed to the FIASCO output file where it is read and used by the
+decoder.
+
+.TP
+half_pixel_prediction
+A non-zero value enables half pixel precise motion compensated
+prediction. 
+
+.TP
+cross_B_search
+A non-zero value enables the fast Cross-B-Search algorithm to determine
+the motion vectors of an interpolated prediction. Otherwise,
+exhaustive search (in the given search range) is used. 
+
+.TP
+B_as_past_ref
+A non-zero value allows not only I- and P-frames but also B-frames to be
+used for a forward or bi-directional predicion.
+
+.TP
+mantissa, range
+Approximation coefficients are quantized to a small number of
+values (in fixed point format) in the interval [-\fIrange\fP,
++\fIrange\fP]. The number of \fImantissa\fP bits defines the accuracy of
+quantization.
+
+.TP
+dc_mantissa, dc_range
+Approximation coefficients of the DC component are quantized in a
+different way: the number of mantissa bits is given by
+\fIdc_mantissa\fP whereas the quantization interval is given by
+[-\fIdc_range\fP, +\fBdc_range\fP].
+
+.TP
+type
+This value sets the \fItype\fP of progress meter which should be used
+during coding. The following types are available:
+.fi
+\fBFIASCO_PROGRESS_NONE\fP:  no output at all
+.fi
+\fBFIASCO_PROGRESS_BAR\fP: print hash marks (###)
+\fBFIASCO_PROGRESS_PERCENT\fP: percentage meter (50%)
+
+.SH RETURN VALUES
+The function \fBfiasco_c_options_new()\fP returns a pointer to the
+newly allocated coder option object. If an error has been catched, a
+NULL pointer is returned.
+
+All set functions return 1 on success and 0 if an error has been
+catched.  
+
+In case of an error, use the function fiasco_get_error_message(3) to
+get a string with the last error message of FIASCO.
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_decoder "(3), " fiasco_coder (3)
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_basisfile.3 b/converter/other/fiasco/doc/fiasco_c_options_set_basisfile.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_basisfile.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_chroma_quality.3 b/converter/other/fiasco/doc/fiasco_c_options_set_chroma_quality.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_chroma_quality.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_comment.3 b/converter/other/fiasco/doc/fiasco_c_options_set_comment.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_comment.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_frame_pattern.3 b/converter/other/fiasco/doc/fiasco_c_options_set_frame_pattern.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_frame_pattern.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_optimizations.3 b/converter/other/fiasco/doc/fiasco_c_options_set_optimizations.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_optimizations.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_prediction.3 b/converter/other/fiasco/doc/fiasco_c_options_set_prediction.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_prediction.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_progress_meter.3 b/converter/other/fiasco/doc/fiasco_c_options_set_progress_meter.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_progress_meter.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_quantization.3 b/converter/other/fiasco/doc/fiasco_c_options_set_quantization.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_quantization.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_smoothing.3 b/converter/other/fiasco/doc/fiasco_c_options_set_smoothing.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_smoothing.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_tiling.3 b/converter/other/fiasco/doc/fiasco_c_options_set_tiling.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_tiling.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_title.3 b/converter/other/fiasco/doc/fiasco_c_options_set_title.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_title.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_c_options_set_video_param.3 b/converter/other/fiasco/doc/fiasco_c_options_set_video_param.3
new file mode 100644
index 00000000..58b2da44
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_c_options_set_video_param.3
@@ -0,0 +1 @@
+.so man3/fiasco_c_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_coder.3 b/converter/other/fiasco/doc/fiasco_coder.3
new file mode 100644
index 00000000..3d1c6b87
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_coder.3
@@ -0,0 +1,106 @@
+.\" $Id: fiasco_coder.3,v 1.2 2000/10/28 17:39:32 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_coder
+\- compress image files to a FIASCO file
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "int "
+.fi
+.BI "fiasco_coder (char const * const * "image_names ,
+.fi
+.BI "              const char * "fiasco_name ,
+.fi
+.BI "              float "quality ,
+.fi
+.BI "              const fiasco_c_options_t * "options );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco-coder()\fP function compresses the image file(s) given
+by the list of \fIimage_names\fP and creates the new FIASCO output file
+\fIfiasco_name\fP. Besides the approximation \fIquality\fP, several
+compression parameters can be adjusted by the class \fBoptions\fP (see
+fiasco_c_options_new(3)).
+
+.SH ARGUMENTS
+
+.TP
+image_names
+NULL terminated array of image filenames to process. If the first
+array element is "-" or a NULL pointer then FIASCO reads the image
+from standard input. Each array element either has to be an image
+filename or a template of the form:
+
+.ce
+prefix[start-end{+,-}step]suffix
+
+Templates are useful when compressing video streams: e.g., if the template
+"img0[12-01-2].pgm" is given as array element, then FIASCO compresses the
+images img012.pgm, img010.pgm, ..., img002.pgm (in this order).
+
+If a filename is a relative path then the images are searched for in
+the current directory and in the (colon-separated) list of directories
+given by the environment variable \fBFIASCO_IMAGES\fP.
+
+.TP
+fiasco_name
+Name of the FIASCO output file. If the name is "-" or NULL then the
+file is produced on standard output.
+
+If \fIfiasco_name\fP is a relative path and the environment variable
+\fBFIASCO_DATA\fP is a (colon-separated) list of directories, then the
+output file is written to the first (writable) directory of this
+list. Otherwise, the current directory is used to store the output
+file.
+
+.TP
+quality
+Defines the quality of compression. Quality has to be a positive
+value, its typical range is 1.0 (worst) to 100.0 (best). Larger values
+are also allowed - at the cost of exploding encoding times.
+
+.TP
+options
+This "class" encapsulates the various coding and decoding
+parameters. Use the functions fiasco_c_options_new(3) and
+fiasco_c_options_delete(3) to create and delete an object of this
+class. Several member functions (see fiasco_c_options(3)) are
+available to change the default values.
+
+.SH RETURN VALUE
+The function \fBfiasco_coder()\fP returns 1 if the FIASCO file has
+been successfully written. If an error has been catched during
+compression, 0 is returned - use the function
+fiasco_get_error_message(3) to get the last error message of FIASCO.
+
+.SH ENVIRONMENT
+.PD 0
+.TP
+.B FIASCO_IMAGES
+Search path for image files. Default is "./".
+.TP
+.B FIASCO_DATA
+Search and save path for FIASCO files. Default is "./".
+.PD 
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_c_options_new "(3), " fiasco_c_options_delete (3), 
+.br
+.BR fiasco_c_options "(3), " fiasco_get_error_message (3)
+.br
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_d_options.3 b/converter/other/fiasco/doc/fiasco_d_options.3
new file mode 100644
index 00000000..21f1db63
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_d_options.3
@@ -0,0 +1 @@
+.so man3/fiasco_d_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_d_options_delete.3 b/converter/other/fiasco/doc/fiasco_d_options_delete.3
new file mode 100644
index 00000000..21f1db63
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_d_options_delete.3
@@ -0,0 +1 @@
+.so man3/fiasco_d_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_d_options_new.3 b/converter/other/fiasco/doc/fiasco_d_options_new.3
new file mode 100644
index 00000000..4294330a
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_d_options_new.3
@@ -0,0 +1,122 @@
+.\" $Id: fiasco_d_options_new.3,v 1.1 2000/10/28 17:35:12 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_d_options_new, fiasco_d_options_set_magnification,
+.B fiasco_d_options_delete, fiasco_d_options_set_smoothing
+.B fiasco_d_options_set_4_2_0_format
+\- define additional options of FIASCO decoder 
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_d_options_t *"
+.fi
+.BI "fiasco_d_options_new"
+.fi
+.BI "   (void);"
+.sp
+.BI "void"
+.fi
+.BI "fiasco_d_options_delete"
+.fi
+.BI "   (fiasco_d_options_t * "options );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_d_options_set_4_2_0_format"
+.fi
+.BI "   (fiasco_d_options_t * "options ,
+.fi
+.BI "    int "format );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_d_options_set_magnification"
+.fi
+.BI "   (fiasco_d_options_t * "options ,
+.fi
+.BI "    int "level );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_d_options_set_smoothing"
+.fi
+.BI "   (fiasco_d_options_t * "options ,
+.fi
+.BI "    unsigned "smoothing );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_d_options_new()\fP function allocates and initializes a
+FIASCO options object which is used to control additional
+decompression parameters.
+
+Conversely, the function \fBfiasco_d_options_delete()\fP discards the
+given FIASCO decoder options object.
+
+Several member functions are available to modify the default behavior
+of the FIASCO decoder.
+
+\fBfiasco_d_options_set_smoothing()\fP sets the
+\fIsmoothing\fP-percentage along partitioning borders when the images
+are regenerated; default is 70.
+
+\fBfiasco_d_options_set_magnification()\fP sets the \fImagnification\fP
+of the regenerated image; default is 0, i.e., the image geometry is
+not changed.
+
+\fBfiasco_d_options_set_4_2_0_format()\fP defines whether the decoder
+should use the default 4:4:4 format or the 4:2:0 format. The latter
+one significantly reduces the decoding time at the cost of some
+additional blocking artefacts.
+
+.SH ARGUMENTS
+.TP
+options
+This object encapsulates various decoding parameters.  
+
+.TP
+smoothing
+This percentage (range is 0 - i.e., no smoothing - to 100) defines how
+much the regenerated image is smoothed along the partitioning borders.
+
+.TP
+level
+This value gives the magnification of the decoded image with respect
+to the original size. Positive values increase and negative values
+decrease the width and height of the image by a factor of
+2^abs(\fIlevel\fP).
+
+.TP
+format
+If \fIformat\fP is 0 then the 4:4:4 color image format is used, i.e.,
+the chroma channel are of the same size as the luminance. Otherwise,
+the 4:2:0 format is used. Then, width and height of each chroma
+channel is only one half of the width and height of the luminance.
+
+.SH RETURN VALUES
+The function \fBfiasco_d_options_new()\fP returns a pointer to the
+newly allocated decoder option object. If an error has been catched, a
+NULL pointer is returned.
+
+All set functions return 1 on success and 0 if an error has been
+catched.  
+
+In case of an error, use the function fiasco_get_error_message(3) to
+get a string with the last error message of FIASCO.
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_decoder "(3), " fiasco_coder (3)
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_d_options_set_4_2_0_format.3 b/converter/other/fiasco/doc/fiasco_d_options_set_4_2_0_format.3
new file mode 100644
index 00000000..21f1db63
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_d_options_set_4_2_0_format.3
@@ -0,0 +1 @@
+.so man3/fiasco_d_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_d_options_set_magnification.3 b/converter/other/fiasco/doc/fiasco_d_options_set_magnification.3
new file mode 100644
index 00000000..21f1db63
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_d_options_set_magnification.3
@@ -0,0 +1 @@
+.so man3/fiasco_d_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_d_options_set_smoothing.3 b/converter/other/fiasco/doc/fiasco_d_options_set_smoothing.3
new file mode 100644
index 00000000..21f1db63
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_d_options_set_smoothing.3
@@ -0,0 +1 @@
+.so man3/fiasco_d_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder.3 b/converter/other/fiasco/doc/fiasco_decoder.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_delete.3 b/converter/other/fiasco/doc/fiasco_decoder_delete.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_delete.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_comment.3 b/converter/other/fiasco/doc/fiasco_decoder_get_comment.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_comment.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_frame.3 b/converter/other/fiasco/doc/fiasco_decoder_get_frame.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_frame.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_framerate.3 b/converter/other/fiasco/doc/fiasco_decoder_get_framerate.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_framerate.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_height.3 b/converter/other/fiasco/doc/fiasco_decoder_get_height.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_height.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_length.3 b/converter/other/fiasco/doc/fiasco_decoder_get_length.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_length.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_title.3 b/converter/other/fiasco/doc/fiasco_decoder_get_title.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_title.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_get_width.3 b/converter/other/fiasco/doc/fiasco_decoder_get_width.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_get_width.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_is_color.3 b/converter/other/fiasco/doc/fiasco_decoder_is_color.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_is_color.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_decoder_new.3 b/converter/other/fiasco/doc/fiasco_decoder_new.3
new file mode 100644
index 00000000..05e981a9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_new.3
@@ -0,0 +1,194 @@
+.\" $Id: fiasco_decoder_new.3,v 1.5 2000/10/28 17:39:32 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_decoder_new, fiasco_decoder_delete,
+.B fiasco_decoder_write_frame, fiasco_decoder_get_frame,
+.B fiasco_decoder_get_length, fiasco_decoder_get_rate,
+.B fiasco_decoder_get_width, fiasco_decoder_get_height
+.B fiasco_decoder_get_title, fiasco_decoder_get_comment
+.B fiasco_decoder_is_color
+\- decompress a FIASCO file
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_decoder_t *"
+.fi
+.BI "fiasco_decoder_new (const char * "fiasco_name ,
+.fi
+.BI "                    const fiasco_d_options_t * "options );
+.sp
+.BI "void"
+.fi
+.BI "fiasco_decoder_delete (fiasco_decoder_t * "decoder );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_decoder_write_frame (fiasco_decoder_t * "decoder ,
+.fi
+.BI "                            const char * "image_name );
+.sp
+.BI "fiasco_image_t *"
+.fi
+.BI "fiasco_decoder_get_frame (fiasco_decoder_t * "decoder );
+.sp
+.BI "unsigned"
+.fi
+.BI "fiasco_decoder_get_length (fiasco_decoder_t * "decoder );
+.sp
+.BI "unsigned"
+.fi
+.BI "fiasco_decoder_get_rate (fiasco_decoder_t * "decoder );
+.sp
+.BI "unsigned"
+.fi
+.BI "fiasco_decoder_get_width (fiasco_decoder_t * "decoder );
+.sp
+.BI "unsigned"
+.fi
+.BI "fiasco_decoder_get_height (fiasco_decoder_t * "decoder );
+.sp
+.BI "const char *"
+.fi
+.BI "fiasco_decoder_get_title (fiasco_decoder_t * "decoder );
+.sp
+.BI "const char *"
+.fi
+.BI "fiasco_decoder_get_comment (fiasco_decoder_t * "decoder );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_decoder_is_color (fiasco_decoder_t * "decoder );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_decoder_new()\fP function initializes the decompression
+of FIASCO file \fIfiasco_name\fP. Several decompression parameters
+can be adjusted by the class \fIoptions\fP (see
+fiasco_d_options_new(3)).
+
+The individual frames of a FIASCO video can be decompressed by calling
+successively either function \fBfiasco_decoder_write_frame()\fP or
+\fBfiasco_decoder_get_frame()\fP.
+
+The function \fBfiasco_decoder_write_frame()\fP decompresses the
+current frame and writes it in raw pgm(5) or ppm(5) format to the file
+\fIimage_name\fP. If \fIimage_name\fP=- or a NULL pointer then the
+image file is produced on the standard output. If \fIimage_name\fP is a
+relative path and the environment variable \fBFIASCO_IMAGES\fP is a
+(colon-separated) list of directories, then the output file is
+written to the first (writable) directory of this list. Otherwise, the
+current directory is used to store the file.
+
+The function \fBfiasco_decoder_get_frame()\fP decompresses the
+current frame and returns the computed image object. Use the function
+fiasco_renderer_new(3) to create a renderer object that converts the
+FIASCO image to the desired format. 
+
+After all frames have been decompressed, the function
+\fBfiasco_decoder_delete()\fP should be called to close the input file
+and to free temporarily allocated memory.
+
+Number of available frames, frame rate and frames geometry, type of the
+FIASCO file are accessible through member functions
+\fBfiasco_decoder_get_length()\fP,
+\fBfiasco_decoder_get_rate()\fP,  
+\fBfiasco_decoder_get_width()\fP,
+\fBfiasco_decoder_get_height()\fP,
+and \fBfiasco_decoder_is_color()\fP. Use \fBfiasco_decoder_get_title()\fP,
+\fBfiasco_decoder_get_comment()\fP to read title and comment strings of the
+FIASCO file. 
+
+.SH ARGUMENTS
+
+.TP
+fiasco_name
+Filename of the FIASCO input file. If \fIfiasco_name\fP is a NULL pointer
+or "-" then the decoder reads from standard input. If the file is not
+found in the current directory and the environment variable
+\fBFIASCO_DATA\fP is a (colon-separated) list of directories, then the
+input file is searched for in these directories, too.
+
+.TP
+options
+This "class" encapsulates the various coding and decoding
+parameters. Use the functions fiasco_d_options_new(3) and
+fiasco_d_options_delete(3) to create and delete an object of this
+class. Several member functions (see fiasco_d_options(3)) are
+available to change the default values.
+
+.TP
+decoder
+The decoder "class" encapsulates the FIASCO decoder. It is used to
+store the internal state of the decoder.
+
+.SH RETURN VALUES
+The function \fBfiasco_decoder_new()\fP returns a pointer to the newly
+allocated decoder object. If an error has been catched, a NULL pointer
+is returned.
+
+The function \fBfiasco_decoder_write_frame()\fP returns 1 if the file
+has been successfully written. Otherwise, the function returns 0.
+
+The function \fBfiasco_decoder_get_frame()\fP returns a pointer to the
+newly allocated FIASCO image object. If an error has been catched, a NULL
+pointer is returned.
+
+The function \fBfiasco_decoder_get_length()\fP returns the number of
+frames of the FIASCO file. If an error has been catched, 0 is
+returned. 
+
+The function \fBfiasco_decoder_get_rate()\fP returns the
+framerate (number of frames per second) of the FIASCO file. If an
+error has been catched, 0 is returned.
+
+The function \fBfiasco_decoder_get_width()\fP returns the width of the
+decoded frames of the FIASCO file. If an error has been catched, 0 is
+returned.
+
+The function \fBfiasco_decoder_get_height()\fP returns the height of the
+decoded frames of the FIASCO file. If an error has been catched, 0 is
+returned.
+
+The function \fBfiasco_decoder_get_title()\fP returns an optional
+title of the FIASCO file. If an error has been catched, 0 is returned.
+
+The function \fBfiasco_decoder_get_comment()\fP returns an optional
+comment of the FIASCO file. If an error has been catched, 0 is returned.
+
+The function \fBfiasco_decoder_is_color()\fP returns 0 if the decoded
+frames are grayscale images, otherwise a non-zero value is
+returned.
+
+In case of an error in one of the above functions, use the function
+fiasco_get_error_message(3) to get a string describing the last error
+message of FIASCO.
+
+.SH ENVIRONMENT
+.PD 0
+.TP
+.B FIASCO_IMAGES
+Search path for image files. Default is "./".
+.TP
+.B FIASCO_DATA
+Search and save path for FIASCO files. Default is "./".
+.PD 
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_d_options_new "(3), " fiasco_d_options_delete (3), 
+.br
+.BR fiasco_d_options "(3), " fiasco_get_error_message (3)
+.br
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_decoder_write_frame.3 b/converter/other/fiasco/doc/fiasco_decoder_write_frame.3
new file mode 100644
index 00000000..33c0d21b
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_decoder_write_frame.3
@@ -0,0 +1 @@
+.so man3/fiasco_decoder_new.3
diff --git a/converter/other/fiasco/doc/fiasco_get_error_message.3 b/converter/other/fiasco/doc/fiasco_get_error_message.3
new file mode 100644
index 00000000..09d593fb
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_get_error_message.3
@@ -0,0 +1,41 @@
+.\" $Id: fiasco_get_error_message.3,v 1.1 2000/06/14 19:07:02 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_get_error_message
+\- return string describing last error catched in FIASCO library
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "const char * "
+.fi
+.BI "fiasco_get_error_message (void);"
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_get_error_message()\fP function returns a string
+describing the last error that has been catched in the FIASCO library.
+
+.SH RETURN VALUE
+The function \fBfiasco_get_error_message()\fP returns the appropriate
+description string, or an empty string if no error has been catched so
+far.
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_options "(3), " fiasco_coder (3), 
+.br
+.BR fiasco_decoder "(3), " fiasco_renderer (3)
+.br
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_get_verbosity.3 b/converter/other/fiasco/doc/fiasco_get_verbosity.3
new file mode 100644
index 00000000..884cd19e
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_get_verbosity.3
@@ -0,0 +1 @@
+.so man3/fiasco_set_verbosity.3
diff --git a/converter/other/fiasco/doc/fiasco_image.3 b/converter/other/fiasco/doc/fiasco_image.3
new file mode 100644
index 00000000..f8df38d5
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_image.3
@@ -0,0 +1 @@
+.so man3/fiasco_image_new.3
diff --git a/converter/other/fiasco/doc/fiasco_image_delete.3 b/converter/other/fiasco/doc/fiasco_image_delete.3
new file mode 100644
index 00000000..f8df38d5
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_image_delete.3
@@ -0,0 +1 @@
+.so man3/fiasco_image_new.3
diff --git a/converter/other/fiasco/doc/fiasco_image_get_height.3 b/converter/other/fiasco/doc/fiasco_image_get_height.3
new file mode 100644
index 00000000..f8df38d5
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_image_get_height.3
@@ -0,0 +1 @@
+.so man3/fiasco_image_new.3
diff --git a/converter/other/fiasco/doc/fiasco_image_get_width.3 b/converter/other/fiasco/doc/fiasco_image_get_width.3
new file mode 100644
index 00000000..f8df38d5
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_image_get_width.3
@@ -0,0 +1 @@
+.so man3/fiasco_image_new.3
diff --git a/converter/other/fiasco/doc/fiasco_image_is_color.3 b/converter/other/fiasco/doc/fiasco_image_is_color.3
new file mode 100644
index 00000000..f8df38d5
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_image_is_color.3
@@ -0,0 +1 @@
+.so man3/fiasco_image_new.3
diff --git a/converter/other/fiasco/doc/fiasco_image_new.3 b/converter/other/fiasco/doc/fiasco_image_new.3
new file mode 100644
index 00000000..10625b63
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_image_new.3
@@ -0,0 +1,95 @@
+.\" $Id: fiasco_image_new.3,v 1.2 2000/06/14 19:26:06 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_image_new, fiasco_image_delete, fiasco_image_get_width,
+.B  fiasco_image_get_height,  fiasco_image_is_color
+\- handle FIASCO image objects
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_image_t *"
+.fi
+.BI "fiasco_image_new (const char * "filename );
+.sp
+.BI "void"
+.fi
+.BI "fiasco_image_delete (fiasco_image_t * "image );
+.sp
+.BI "unsigned"
+.fi
+.BI "fiasco_image_get_width (const fiasco_image_t * "image );
+.sp
+.BI "unsigned"
+.fi
+.BI "fiasco_image_get_height (const fiasco_image_t * "image );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_image_is_color (const fiasco_image_t * "image );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_image_new()\fP function reads the given image file and
+allocates and initializes a FIASCO image object. Use the function
+fiasco_renderer_new(3) to create a renderer object that converts the
+FIASCO image to the desired image format.
+
+The function \fBfiasco_image_delete()\fP deletes the image object and
+frees the image buffer. 
+
+Image geometry and type are accessible through member functions
+\fBfiasco_image_get_width()\fP,
+\fBfiasco_image_get_height()\fP,
+and \fBfiasco_image_is_color()\fP. 
+
+.SH ARGUMENTS
+
+.TP
+image
+The image "class" encapsulates the FIASCO image object. It is used to
+store the pixel values of the decoded or read image.
+
+.TP
+filename
+Image filename to process. If \fIfilename\fP is "-" or a NULL pointer
+then the image is read from standard input. If a filename is a
+relative path then the images are searched for in the current
+directory and in the (colon-separated) list of directories given by
+the environment variable \fBFIASCO_IMAGES\fP.
+
+.SH RETURN VALUE
+The function \fBfiasco_image_new()\fP returns a pointer to the newly
+allocated image object. If an error has been catched, a NULL pointer
+is returned.
+
+The function \fBfiasco_image_get_width()\fP returns the width of the
+image. If an error has been catched, 0 is returned.
+
+The function \fBfiasco_image_get_height()\fP returns the height of the
+image. If an error has been catched, 0 is returned.
+
+The function \fBfiasco_image_is_color()\fP returns 0 if the image
+object is a grayscale image, otherwise a non-zero value is returned.
+
+In case of an error in one of the above functions, use the function
+fiasco_get_error_message(3) to get a string with the last error
+message of FIASCO.
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_decoder_get_frame "(3), " fiasco_get_error_message (3)
+.BR fiasco_renderer_new (3)
+.br
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_options.3 b/converter/other/fiasco/doc/fiasco_options.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_delete.3 b/converter/other/fiasco/doc/fiasco_options_delete.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_delete.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_new.3 b/converter/other/fiasco/doc/fiasco_options_new.3
new file mode 100644
index 00000000..26e070ca
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_new.3
@@ -0,0 +1,441 @@
+.\" $Id: fiasco_options_new.3,v 1.2 2000/06/25 16:38:06 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_options_new, fiasco_options_set_magnification,
+.B fiasco_options_delete, fiasco_options_set_progress_meter,
+.B fiasco_options_set_smoothing, fiasco_options_set_tiling, 
+.B fiasco_options_set_4_2_0_format, fiasco_options_set_basisfile,
+.B fiasco_options_set_chroma_quality, fiasco_options_set_optimizations,
+.B fiasco_options_set_prediction, fiasco_options_set_video_param,
+.B fiasco_options_set_quantization, fiasco_options_set_frame_pattern
+\- define additional options of FIASCO coder and decoder 
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_options_t *"
+.fi
+.BI "fiasco_options_new"
+.fi
+.BI "   (void);"
+.sp
+.BI "void"
+.fi
+.BI "fiasco_options_delete"
+.fi
+.BI "   (fiasco_options_t * "options );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_4_2_0_format"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    int "format );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_basisfile"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    const char * "filename );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_chroma_quality"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    float "quality_factor ,
+.fi
+.BI "    unsigned "dictionary_size );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_frame_pattern"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    const char * "pattern );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_magnification"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    int "level );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_optimizations"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    unsigned "min_block_level ,
+.fi
+.BI "    unsigned "max_block_level ,
+.fi
+.BI "    unsigned "max_elements ,
+.fi
+.BI "    unsigned "dictionary_size ,
+.fi
+.BI "    unsigned "optimization_level );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_quantization"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    unsigned "mantissa ,
+.fi
+.BI "    fiasco_rpf_range_e "range ,
+.fi
+.BI "    unsigned "dc_mantissa ,
+.fi
+.BI "    fiasco_rpf_range_e "dc_range );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_prediction"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    int "intra_prediction ,
+.fi
+.BI "    unsigned "min_block_level ,
+.fi
+.BI "    unsigned "max_block_level );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_progress_meter"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    fiasco_progress_e "type );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_smoothing"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    unsigned "smoothing );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_tiling"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    fiasco_tiling_e "method ,
+.fi
+.BI "    unsigned "exponent );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_options_set_video_param"
+.fi
+.BI "   (fiasco_options_t * "options ,
+.fi
+.BI "    unsigned "frames_per_second ,
+.fi
+.BI "    int "half_pixel_prediction ,
+.fi
+.BI "    int "cross_B_search ,
+.fi
+.BI "    int "B_as_past_ref );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_options_new()\fP function allocates and initializes a
+FIASCO options object which is used to control additional compression and
+decompression parameters.
+
+Conversely, the function \fBfiasco_options_delete()\fP discards the
+given FIASCO options object.
+
+Several member functions are available to modify the default behavior
+of the FIASCO coder and decoder. 
+
+\fBfiasco_options_set_smoothing()\fP sets the
+\fIsmoothing\fP-percentage along partitioning borders when the image
+is regenerated; default is 70. This option is used both by the decoder
+and encoder. You should use the \fIsmoothing\fP value specified in the
+FIASCO file when you are decoding video frames.
+
+\fBfiasco_options_set_magnification()\fP sets the \fImagnification\fP
+of the regenerated image; default is 0, i.e., the image geometry is
+not changed. This option is used by the decoder only.
+
+\fBfiasco_options_set_4_2_0_format()\fP defines whether the decoder
+should use the default 4:4:4 format or the 4:2:0 format. The latter
+one significantly reduces the decoding time at the cost of some
+additional blocking artefacts. This option is used by the decoder only.
+
+\fBfiasco_options_set_frame_pattern()\fP sets the type of inter frame
+compression which should be applied to individual frames of a video
+stream; default is "IPPPPPPPPP". 
+
+\fBfiasco_options_set_tiling()\fP sets \fImethod\fP and \fIexponent\fP
+of the image tiling algorithm which runs as initial step of the
+encoder; by default the image is subdivided into 16 tiles which
+are sorted by decreasing variance. 
+
+\fBfiasco_options_set_basisfile()\fP sets the \fIfilename\fP of
+the FIASCO initial basis (codebook of dictionary vectors); default is
+"small.fco". 
+
+\fBfiasco_options_set_chroma_quality()\fP sets the quality used when
+coding the chroma channels of a color image to the term "\fIquality\fP
+of luminance / \fIquality_factor\fP"; default is 2. Moreover, the size
+of the codebook is limited by \fIdictionary_size\fP; default is 40
+elements. 
+
+\fBfiasco_options_set_optimizations()\fP toggles various coding
+optimizations. E.g., the size of the dictionary (default is 10000),
+the subset of dictionary elements to use for an individual
+approximation (default is 5), the size of the image blocks to consider
+(4x4, ..., 64x64), and some additional low level
+optimizations (default level is 1). 
+
+\fBfiasco_options_set_prediction()\fP enables an additional intra
+block prediction by using a DC component approximation. By giving
+levels \fImin_block_level\fP and \fImax_block_level\fP the prediction
+can be limited to a small range of blocks only. By default, this
+method is disabled. 
+
+\fBfiasco_options_set_video_param()\fP defines the framerate (default
+is 25) and toggles whether to use half pixel precise motion
+compensated prediction (disabled by default), whether to determine
+motion vectors of interpolated prediction with the Cross-B-Search
+algorithm (disabled by default), and whether to allow B frames to be
+used for B frame predicion (disabled by default).
+
+\fBfiasco_options_set_quantization()\fP defines the quantization
+parameters of the approximation coefficients. By default the range of
+DC coefficients is [-1,+1] using a mantissa of 5 bits (and one sign
+bit). By default, all other coefficients are quantized with 3 mantissa
+bits in the interval [-1.5,+1.5].
+
+\fBfiasco_options_set_progress_meter()\fP sets the type of progress
+meter to be used during coding. By default, an RPM style progress bar
+using 50 hash marks (####) is used.
+
+.SH ARGUMENTS
+.TP
+options
+This object encapsulates the various coding and decoding parameters.  
+
+.TP
+smoothing
+This percentage (range is 0 - i.e., no smoothing - to 100) defines how
+much the regenerated image is smoothed along the partitioning borders.
+
+.TP
+level
+This value gives the magnification of the decoded image with respect
+to the original size. Positive values increase and negative values
+decrease the width and height of the image by a factor of
+2^abs(\fIlevel\fP).
+
+.TP
+format
+If \fIformat\fP is 0 then the 4:4:4 color image format is used, i.e.,
+the chroma channel are of the same size as the luminance. Otherwise,
+the 4:2:0 format is used. Then, width and height of each chroma
+channel is only one half of the width and height of the luminance.
+
+.TP
+method
+Defines the algorithm which should be used to sort the image tiles
+which are generated in the initial coding step. If \fImethod\fP is
+\fBFIASCO_VARIANCE_ASC\fP then the tiles are sorted by variance - the
+first tile has the lowest variance. Conversely, when using
+\fBFIASCO_VARIANCE_DSC\fP the first tile has the largest variance. If
+\fImethod\fP is \fBFIASCO_SPIRAL_ASC\fP then the tiles are sorted like
+a spiral starting in the middle of the image. Conversely, when using
+\fBFIASCO_SPIRAL_DSC\fP the tiles are sorted like a spiral starting in
+the upper left corner.
+
+.TP
+exponent
+This value sets the number of image tiles - which are generated in the
+initial step of the encoder - to 2^\fIexponent\fP.
+
+.TP
+pattern
+This string defines the sequence of frame types. Character \fIn\fP of
+the string defines the type of frame \fIn\fP (\fIpattern\fP is
+periodically extended). Three different frame types are available
+(case insensitive): choose 'i' for intra-frames (no inter frame
+prediction is used), 'p' for predicted frames (a frame of the
+past is used for prediction), or 'b' for bi-directional predicted
+frames (both a frame of the past and the future is used for
+prediction).
+
+.TP
+filename
+The initial basis (codebook) of the coder is loaded from this
+(ASCII) file. Files that already come with FIASCO are "small.fco" (3 elements),
+"medium.fco" (132 elements), and "large.fco" (219 elements). 
+
+.TP
+quality_factor
+When coding chroma channels (Cb and Cr band) the approximation quality
+is determined by the term `quality of Y component' / \fIquality_factor\fP.
+
+.TP
+dictionary_size
+FIASCO uses a dictionary (codebook) of variable size to approximate
+individual image blocks. The size of the codebook can be limited by
+\fIdictionary_size\fP to reduce the coding time, however, at the cost
+of decreasing quality. 
+
+.TP
+min_block_level
+During coding only those image blocks are considered for approximation
+(or prediction) which binary tree level is larger than
+\fImin_block_level\fP (minimum value is 3). (Since FIASCO internally
+works with binary trees, the size of an image block is determined by
+the \fIlevel\fP of the corresponding binary tree). Refer to following
+table to convert these values:
+
+.ce
+level | width | height
+.fi
+------+-------+--------
+.fi
+  0   |    1  |    1  
+.fi
+  1   |    1  |    2  
+.fi
+  2   |    2  |    2  
+.fi
+  3   |    2  |    4  
+.fi
+  4   |    4  |    4  
+.fi
+  5   |    4  |    8  
+.fi
+  6   |    8  |    8  
+.fi
+  7   |    8  |   16
+.fi
+------+-------+--------
+.fi
+The larger this value is the faster the coder runs but the worse the
+image quality will be.
+
+.TP
+max_block_level
+During coding only those image blocks are considered for approximation
+(or prediction) which binary tree level is smaller than
+\fImax_block_level\fP. The smaller this value is the faster the coder
+runs but the worse the image quality will be.
+
+.TP
+max_elements
+This value defines how many dictionary elements can be
+used to approximate an individual image block. The smaller this positive
+value (range is 1 to 5) is the faster the coder runs but the worse the
+image quality will be. 
+
+.TP
+optimization_level
+Additional low level optimizations are available by setting
+\fIoptimization_level\fP to one of the following values:
+.fi
+0 standard approximation method
+.fi
+1 slightly increases the approximation quality, running time is
+twice as high as with the standard method 
+.fi
+2 hardly increases the approximation quality of method 1, running time
+is twice as high as with method 1 (this method just remains for
+completeness) 
+.fi
+
+.TP
+intra_prediction
+If \fIintra_prediction\fP is set to a non-zero value then an
+additional block prediction of intra-frames is enabled. For some
+images, the image quality is slightly improved, however, at the cost of
+a significantly increased running time of the coder. 
+
+.TP
+frames_per_second
+This value defines the frame rate, i.e., how many frames per second
+should be displayed. This value has no effect during coding, it is just
+passed to the FIASCO output file where it is read and used by the
+decoder.
+
+.TP
+half_pixel_prediction
+A non-zero value enables half pixel precise motion compensated
+prediction. 
+
+.TP
+cross_B_search
+A non-zero value enables the fast Cross-B-Search algorithm to determine
+the motion vectors of an interpolated prediction. Otherwise,
+exhaustive search (in the given search range) is used. 
+
+.TP
+B_as_past_ref
+A non-zero value allows not only I- and P-frames but also B-frames to be
+used for a forward or bi-directional predicion.
+
+.TP
+mantissa, range
+Approximation coefficients are quantized to a small number of
+values (in fixed point format) in the interval [-\fIrange\fP,
++\fIrange\fP]. The number of \fImantissa\fP bits defines the accuracy of
+quantization.
+
+.TP
+dc_mantissa, dc_range
+Approximation coefficients of the DC component are quantized in a
+different way: the number of mantissa bits is given by
+\fIdc_mantissa\fP whereas the quantization interval is given by
+[-\fIdc_range\fP, +\fBdc_range\fP].
+
+.TP
+type
+This value sets the \fItype\fP of progress meter which should be used
+during coding. The following types are available:
+.fi
+\fBFIASCO_PROGRESS_NONE\fP:  no output at all
+.fi
+\fBFIASCO_PROGRESS_BAR\fP: print hash marks (###)
+\fBFIASCO_PROGRESS_PERCENT\fP: percentage meter (50%)
+
+.SH RETURN VALUES
+The function \fBfiasco_decoder_new()\fP returns a pointer to the newly
+allocated option object. If an error has been catched, a NULL pointer
+is returned.
+
+All set functions return 1 on success and 0 if an error has been
+catched.  
+
+In case of an error, use the function fiasco_get_error_message(3) to
+get a string with the last error message of FIASCO.
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_decoder "(3), " fiasco_coder (3)
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_options_set_4_2_0_format.3 b/converter/other/fiasco/doc/fiasco_options_set_4_2_0_format.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_4_2_0_format.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_basisfile.3 b/converter/other/fiasco/doc/fiasco_options_set_basisfile.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_basisfile.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_chroma_quality.3 b/converter/other/fiasco/doc/fiasco_options_set_chroma_quality.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_chroma_quality.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_frame_pattern.3 b/converter/other/fiasco/doc/fiasco_options_set_frame_pattern.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_frame_pattern.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_magnification.3 b/converter/other/fiasco/doc/fiasco_options_set_magnification.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_magnification.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_optimizations.3 b/converter/other/fiasco/doc/fiasco_options_set_optimizations.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_optimizations.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_prediction.3 b/converter/other/fiasco/doc/fiasco_options_set_prediction.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_prediction.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_progress_meter.3 b/converter/other/fiasco/doc/fiasco_options_set_progress_meter.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_progress_meter.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_quantization.3 b/converter/other/fiasco/doc/fiasco_options_set_quantization.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_quantization.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_smoothing.3 b/converter/other/fiasco/doc/fiasco_options_set_smoothing.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_smoothing.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_tiling.3 b/converter/other/fiasco/doc/fiasco_options_set_tiling.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_tiling.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_options_set_video_param.3 b/converter/other/fiasco/doc/fiasco_options_set_video_param.3
new file mode 100644
index 00000000..493fcce9
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_options_set_video_param.3
@@ -0,0 +1 @@
+.so man3/fiasco_options_new.3
diff --git a/converter/other/fiasco/doc/fiasco_renderer.3 b/converter/other/fiasco/doc/fiasco_renderer.3
new file mode 100644
index 00000000..0aec996e
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_renderer.3
@@ -0,0 +1 @@
+.so man3/fiasco_renderer_new.3
diff --git a/converter/other/fiasco/doc/fiasco_renderer_delete.3 b/converter/other/fiasco/doc/fiasco_renderer_delete.3
new file mode 100644
index 00000000..0aec996e
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_renderer_delete.3
@@ -0,0 +1 @@
+.so man3/fiasco_renderer_new.3
diff --git a/converter/other/fiasco/doc/fiasco_renderer_new.3 b/converter/other/fiasco/doc/fiasco_renderer_new.3
new file mode 100644
index 00000000..b24d8462
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_renderer_new.3
@@ -0,0 +1,125 @@
+.\" $Id: fiasco_renderer_new.3,v 1.2 2000/06/14 18:58:35 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_renderer_new, fiasco_renderer_delete
+\- convert a FIASCO image object to an X11 XImage
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_renderer_t *"
+.fi
+.BI "fiasco_renderer_new (unsigned long "red_mask ,
+.fi
+.BI "                     unsigned long "green_mask ,
+.fi
+.BI "                     unsigned long "blue_mask ,
+.fi
+.BI "                     unsigned "bpp ,
+.fi
+.BI "                     int "double_resolution );
+.sp
+.BI "void"
+.fi
+.BI "fiasco_renderer_delete (fiasco_renderer_t * "renderer );
+.sp
+.BI "int"
+.fi
+.BI "fiasco_renderer_render (const fiasco_renderer_t * "renderer ,
+.fi
+.BI "                        unsigned char * "data );
+.fi
+.BI "                        const fiasco_image_t * "fiasco_image );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_renderer_new()\fP function allocates and initializes a
+renderer object which has to be used to convert an internal FIASCO
+image object to one of the supported X11 formats. Currently, the FIASCO
+image can be rendered to an X11 XImage of either 16, 24, or 32 bits
+per pixel. Additional formats will be supported upon request.  
+
+Function \fBfiasco_renderer_render()\fP is used to convert the given
+FIASCO image object to the specified format. 
+
+After all frames are rendered, the function
+\fBfiasco_renderer_delete()\fP should be called to free temporarily
+allocated memory and to discard the renderer object.
+
+Note that the FIASCO renderer class is not restricted to X11 images: a
+FIASCO image object can be converted to an image data array of the
+form RGBRGB... by setting \fIred_mask\fP=0xff0000,
+\fIgreen_mask\fP=0xff00, \fIblue_mask\fP=0xff, and \fIbpp\fP=24.
+
+.SH ARGUMENTS
+
+.TP
+bpp
+Determines the number of bits of a single pixel of the X11 XImage
+structure (see XCreateImage(3)). If the XImage is already allocated
+then the value XImage->bits_per_pixel should be used. Currently, 16,
+24, and 32 bits per pixel are supported.
+
+.TP
+red_mask
+Determines which bits of a pixel should be used for the red
+component. If the XImage is already allocated then the value
+XImage->red_mask should be used. E.g., if \fIbpp=16\fP and
+\fIred_mask=0xf800\fP then each pixel is stored with two bytes. The
+red component uses bits 11-15, the remaining green and blue components
+use bits 0-10.
+
+.TP
+green_mask
+Determines which bits of a pixel should be used for the green
+component. If the XImage is already allocated then the value
+XImage->green_mask should be used.
+
+.TP
+blue_mask
+Determines which bits of a pixel should be used for the blue
+component. If the XImage is already allocated then the value
+XImage->blue_mask should be used.
+
+.TP
+data
+A pointer to the image data. If the XImage is already allocated then
+the value XImage->data should be used. This array has to be large
+enough to hold the decoded image at the given size (geometry and bits
+per pixel).
+
+.TP
+fiasco_image
+This object represents the decoded image which has been
+created by the FIASCO functions fiasco_decoder_get_frame(3) or
+fiasco_image_new(3).
+
+.SH RETURN VALUE
+The function \fBfiasco_renderer_new()\fP returns a pointer to the newly
+allocated renderer object. If an error has been catched, a NULL pointer
+is returned.
+
+The function \fBfiasco_renderer_render()\fP returns 1 if the image
+has been successfully converted. Otherwise, the function returns 0.
+
+In case of an error in one of the above functions, use the function
+fiasco_get_error_message(3) to get a string with the last error
+message of FIASCO.
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_decoder_get_frame "(3), " fiasco_get_error_message (3)
+.BR fiasco_image_new (3)
+.br
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/doc/fiasco_renderer_render.3 b/converter/other/fiasco/doc/fiasco_renderer_render.3
new file mode 100644
index 00000000..0aec996e
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_renderer_render.3
@@ -0,0 +1 @@
+.so man3/fiasco_renderer_new.3
diff --git a/converter/other/fiasco/doc/fiasco_set_verbosity.3 b/converter/other/fiasco/doc/fiasco_set_verbosity.3
new file mode 100644
index 00000000..746854b1
--- /dev/null
+++ b/converter/other/fiasco/doc/fiasco_set_verbosity.3
@@ -0,0 +1,46 @@
+.\" $Id: fiasco_set_verbosity.3,v 1.1 2000/06/06 20:55:05 hafner Exp $
+.TH fiasco 3 "April, 2000" "FIASCO" "Fractal Image And Sequence COdec"
+
+.SH NAME
+.B  fiasco_get_verbosity, fiasco_set_verbosity
+\- get or set verbosity of FIASCO library
+
+.SH SYNOPSIS
+.B #include <fiasco.h>
+.sp
+.BI "fiasco_verbosity_e"
+.fi
+.BI "fiasco_get_verbosity (void);"
+.sp
+.BI "void"
+.fi
+.BI "fiasco_set_verbosity (fiasco_verbosity_e "level );
+.fi
+
+.SH DESCRIPTION
+The \fBfiasco_get_verbosity()\fP function returns the current
+verbosity level of the FIASCO library. Conversely, the function
+\fBfiasco_set_verbosity()\fP sets the verbosity of the FIASCO library
+to the given \fIlevel\fP.
+
+.SH RETURN VALUE
+The function \fBfiasco_get_verbosity()\fP returns the current
+verbosity level. Level either is \fBFIASCO_NO_VERBOSITY\fP (no output at
+all), \fBFIASCO_SOME_VERBOSITY\fP (show progress meter) or
+\fBFIASCO_ULTIMATE_VERBOSITY\fP (show debugging output).
+
+.SH "SEE ALSO"
+.br
+.BR fiasco_coder (3), fiasco_decoder (3)
+.br
+
+Ullrich Hafner, Juergen Albert, Stefan Frank, and Michael Unger.
+\fBWeighted Finite Automata for Video Compression\fP, IEEE Journal on
+Selected Areas In Communications, January 1998
+.br
+Ullrich Hafner. \fBLow Bit-Rate Image and Video Coding with Weighted
+Finite Automata\fP, Ph.D. thesis, Mensch & Buch Verlag, ISBN
+3-89820-002-7, October 1999.
+
+.SH AUTHOR
+Ullrich Hafner <hafner@bigfoot.de>
diff --git a/converter/other/fiasco/fiasco.h b/converter/other/fiasco/fiasco.h
new file mode 100644
index 00000000..235b1279
--- /dev/null
+++ b/converter/other/fiasco/fiasco.h
@@ -0,0 +1,425 @@
+/*
+ *  fiasco.h		
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
+
+/*
+ *  $Date: 2000/10/28 17:39:28 $
+ *  $Author: hafner $
+ *  $Revision: 5.6 $
+ *  $State: Exp $
+ */
+
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+#ifndef _FIASCO_H
+#define _FIASCO_H 1
+
+__BEGIN_DECLS
+
+/****************************************************************************
+			  FIASCO data types
+****************************************************************************/
+
+/*
+ *  Verbosity level:
+ *  FIASCO_NO_VERBOSITY:       No output at all.
+ *  FIASCO_SOME_VERBOSITY:     Show progress meter during coding
+ *  FIASCO_ULTIMATE_VERBOSITY: Show debugging output
+ */
+typedef enum {FIASCO_NO_VERBOSITY,
+	      FIASCO_SOME_VERBOSITY,
+	      FIASCO_ULTIMATE_VERBOSITY} fiasco_verbosity_e;
+  
+/*
+ *  Image tiling methods:
+ *  VARIANCE_ASC:  Tiles are sorted by variance.
+ *                 The first tile has the lowest variance.
+ *  VARIANCE_DSC:  Tiles are sorted by variance.
+ *                 The first tile has the largest variance.
+ *  SPIRAL_ASC:    Tiles are sorted like a spiral starting
+ *                 in the middle of the image.
+ *  SPIRAL_DSC:    Tiles are sorted like a spiral starting
+ *                 in the upper left corner.
+ */
+typedef enum {FIASCO_TILING_SPIRAL_ASC,
+	      FIASCO_TILING_SPIRAL_DSC,
+	      FIASCO_TILING_VARIANCE_ASC,
+	      FIASCO_TILING_VARIANCE_DSC} fiasco_tiling_e;
+
+/*
+ *  Range of reduced precision format:
+ *  FIASCO_RPF_RANGE_0_75: use interval [-0.75,0.75]
+ *  FIASCO_RPF_RANGE_1_00: use interval [-1.00,1.00]
+ *  FIASCO_RPF_RANGE_1_50: use interval [-1.50,0.75]
+ *  FIASCO_RPF_RANGE_2_00: use interval [-2.00,2.00]
+ */
+typedef enum {FIASCO_RPF_RANGE_0_75,
+	      FIASCO_RPF_RANGE_1_00,
+	      FIASCO_RPF_RANGE_1_50,
+	      FIASCO_RPF_RANGE_2_00} fiasco_rpf_range_e;
+
+/*
+ *  Type of progress meter to be used during coding
+ *  FIASCO_PROGRESS_NONE:    no output at all
+ *  FIASCO_PROGRESS_BAR:     RPM style progress bar using 50 hash marks ###### 
+ *  FIASCO_PROGRESS_PERCENT: percentage meter 50% 
+ */
+typedef enum {FIASCO_PROGRESS_NONE,
+	      FIASCO_PROGRESS_BAR,
+	      FIASCO_PROGRESS_PERCENT} fiasco_progress_e;
+
+/*
+ * Class to encapsulate FIASCO images.
+ */
+typedef struct fiasco_image
+{
+   void		(*delete)	(struct fiasco_image *image);
+   unsigned	(*get_width)	(struct fiasco_image *image);
+   unsigned	(*get_height)	(struct fiasco_image *image);
+   int		(*is_color)	(struct fiasco_image *image);
+   void *private;
+} fiasco_image_t;
+
+/*
+ * Class to store internal state of decoder.
+ */
+typedef struct fiasco_decoder
+{
+   int			(*delete)	 (struct fiasco_decoder *decoder);
+   int			(*write_frame)   (struct fiasco_decoder *decoder,
+					  const char *filename);
+   fiasco_image_t *	(*get_frame)     (struct fiasco_decoder *decoder);
+   unsigned		(*get_length)    (struct fiasco_decoder *decoder);
+   unsigned		(*get_rate)	 (struct fiasco_decoder *decoder);
+   unsigned		(*get_width)	 (struct fiasco_decoder *decoder);
+   unsigned		(*get_height)	 (struct fiasco_decoder *decoder);
+   const char *		(*get_title)	 (struct fiasco_decoder *decoder);
+   const char *		(*get_comment)	 (struct fiasco_decoder *decoder);
+   int			(*is_color)	 (struct fiasco_decoder *decoder);
+   void *private;
+} fiasco_decoder_t;
+
+/*
+ * Class to encapsulate advanced coder options.
+ */
+typedef struct fiasco_c_options
+{
+   void (*delete)            (struct fiasco_c_options *options);
+   int (*set_tiling)         (struct fiasco_c_options *options,
+			      fiasco_tiling_e method,
+			      unsigned exponent);
+   int (*set_frame_pattern)  (struct fiasco_c_options *options,
+			      const char *pattern);
+   int (*set_basisfile)      (struct fiasco_c_options *options,
+			      const char *filename);
+   int (*set_chroma_quality) (struct fiasco_c_options *options,
+			      float quality_factor,
+			      unsigned dictionary_size);
+   int (*set_optimizations)  (struct fiasco_c_options *options,
+			      unsigned min_block_level,
+			      unsigned max_block_level,
+			      unsigned max_elements,
+			      unsigned dictionary_size,
+			      unsigned optimization_level);
+   int (*set_prediction)     (struct fiasco_c_options *options,
+			      int intra_prediction,
+			      unsigned min_block_level,
+			      unsigned max_block_level);
+   int (*set_video_param)    (struct fiasco_c_options *options,
+			      unsigned frames_per_second,
+			      int half_pixel_prediction,
+			      int cross_B_search,
+			      int B_as_past_ref);
+   int (*set_quantization)   (struct fiasco_c_options *options,
+			      unsigned mantissa,
+			      fiasco_rpf_range_e range,
+			      unsigned dc_mantissa,
+			      fiasco_rpf_range_e dc_range);
+   int (*set_progress_meter) (struct fiasco_c_options *options,
+			      fiasco_progress_e type);
+   int (*set_smoothing)      (struct fiasco_c_options *options,
+			      int smoothing);
+   int (*set_comment)        (struct fiasco_c_options *options,
+			      const char *comment);
+   int (*set_title)          (struct fiasco_c_options *options,
+			      const char *title);
+   void *private;
+} fiasco_c_options_t;
+
+/*
+ * Class to encapsulate advanced decoder options.
+ */
+typedef struct fiasco_d_options
+{
+   void (*delete)            (struct fiasco_d_options *options);
+   int (*set_smoothing)      (struct fiasco_d_options *options,
+			      int smoothing);
+   int (*set_magnification)  (struct fiasco_d_options *options,
+			      int level);
+   int (*set_4_2_0_format)   (struct fiasco_d_options *options,
+			      int format);
+   void *private;
+} fiasco_d_options_t;
+
+/*
+ * Class to convert internal FIASCO image structure to a XImage structure.
+ * Method `renderer()' is used to convert internal image to XImage. 
+ * Method `delete()' is used to delete and free internal image. 
+ */
+typedef struct fiasco_renderer
+{
+   int  (*render) (const struct fiasco_renderer *this,
+		   unsigned char *data,
+		   const fiasco_image_t *fiasco_image);
+   void (*delete) (struct fiasco_renderer *this);
+   void *private;
+} fiasco_renderer_t;
+
+/****************************************************************************
+		       miscellaneous functions
+****************************************************************************/
+  
+/* Get last error message of FIASCO library */
+const char *fiasco_get_error_message (void);
+
+/* Set verbosity of FIASCO library */
+void fiasco_set_verbosity (fiasco_verbosity_e level);
+
+/* Get verbosity of FIASCO library */
+fiasco_verbosity_e fiasco_get_verbosity (void);
+
+/****************************************************************************
+			  decoder functions
+****************************************************************************/
+
+/* Decode FIASCO image or sequence */
+fiasco_decoder_t *fiasco_decoder_new (const char *filename,
+				      const fiasco_d_options_t *options);
+
+/* Flush and discard FIASCO decoder */
+int fiasco_decoder_delete (fiasco_decoder_t *decoder);
+
+/* Decode next FIASCO frame and write to PNM image 'filename' */
+int fiasco_decoder_write_frame (fiasco_decoder_t *decoder,
+				const char *filename);
+
+/* Decode next FIASCO frame to FIASCO image structure */
+fiasco_image_t *fiasco_decoder_get_frame (fiasco_decoder_t *decoder);
+
+/* Get width of FIASCO image or sequence */
+unsigned fiasco_decoder_get_width (fiasco_decoder_t *decoder);
+
+/* Get height of FIASCO image or sequence */
+unsigned fiasco_decoder_get_height (fiasco_decoder_t *decoder);
+
+/* Get width of FIASCO image or sequence */
+int fiasco_decoder_is_color (fiasco_decoder_t *decoder);
+
+/* Get frame rate of FIASCO sequence */
+unsigned fiasco_decoder_get_rate (fiasco_decoder_t *decoder);
+
+/* Get number of frames of FIASCO file */
+unsigned fiasco_decoder_get_length (fiasco_decoder_t *decoder);
+
+/* Get title of FIASCO file */
+const char *
+fiasco_decoder_get_title (fiasco_decoder_t *decoder);
+
+/* Get comment of FIASCO file */
+const char *
+fiasco_decoder_get_comment (fiasco_decoder_t *decoder);
+
+/****************************************************************************
+			  image functions
+****************************************************************************/
+
+/* Read FIASCO image (raw ppm or pgm format) */
+fiasco_image_t * fiasco_image_new (const char *filename);
+
+/* Discard FIASCO image */
+void fiasco_image_delete (fiasco_image_t *image); 
+
+/* Get width of FIASCO image or sequence */
+unsigned fiasco_image_get_width (fiasco_image_t *image);
+
+/* Get height of FIASCO image or sequence */
+unsigned fiasco_image_get_height (fiasco_image_t *image);
+
+/* Get width of FIASCO image or sequence */
+int fiasco_image_is_color (fiasco_image_t *image);
+
+/****************************************************************************
+			  renderer functions
+****************************************************************************/
+
+/* Constructor of FIASCO image structure to a XImage renderer */
+fiasco_renderer_t *
+fiasco_renderer_new (unsigned long red_mask, unsigned long green_mask,
+		     unsigned long blue_mask, unsigned bpp,
+		     int double_resolution);
+
+/* Destructor of FIASCO image structure to a XImage renderer */
+void
+fiasco_renderer_delete (fiasco_renderer_t *renderer);
+
+/* FIASCO image structure to a XImage renderer */
+int
+fiasco_renderer_render (const fiasco_renderer_t *renderer,
+			unsigned char *ximage,
+			const fiasco_image_t *fiasco_image);
+
+/****************************************************************************
+			   coder functions
+****************************************************************************/
+
+/* Encode image or sequence by FIASCO */
+int fiasco_coder (char const * const *inputname,
+		  const char *outputname,
+		  float quality,
+		  const fiasco_c_options_t *options);
+
+/****************************************************************************
+		 coder options functions
+****************************************************************************/
+
+/* FIASCO additional options constructor */
+fiasco_c_options_t *fiasco_c_options_new (void);
+
+/* FIASCO additional options destructor */
+void fiasco_c_options_delete (fiasco_c_options_t *options);
+
+/* Define `smoothing'-percentage along partitioning borders.*/
+int fiasco_c_options_set_smoothing (fiasco_c_options_t *options,
+				    int smoothing);
+
+/* Set type of frame prediction for sequence of frames */
+int fiasco_c_options_set_frame_pattern (fiasco_c_options_t *options,
+					const char *pattern);
+
+/* Set method and number of tiles for image tiling */
+int fiasco_c_options_set_tiling (fiasco_c_options_t *options,
+				 fiasco_tiling_e method,
+				 unsigned exponent);
+
+/* Set FIASCO initial basis file */
+int fiasco_c_options_set_basisfile (fiasco_c_options_t *options,
+				    const char *filename);
+
+/* Set quality and dictionary size of chroma compression */
+int fiasco_c_options_set_chroma_quality (fiasco_c_options_t *options,
+					 float quality_factor,
+					 unsigned dictionary_size);
+
+/*
+ *  Since FIASCO internally works with binary trees, all functions
+ *  (which are handling image geometry) rather expect the `level' of
+ *  the corresponding binary tree than the traditional `width' and
+ *  `height' arguments.  Refer to following table to convert these
+ *  values:
+ *  
+ *  level | width | height
+ *  ------+-------+--------
+ *    0   |    1  |    1  
+ *    1   |    1  |    2  
+ *    2   |    2  |    2  
+ *    3   |    2  |    4  
+ *    4   |    4  |    4  
+ *    5   |    4  |    8  
+ *    6   |    8  |    8  
+ *    7   |    8  |   16
+ *
+ */
+   
+/* Set various optimization parameters. */
+int fiasco_c_options_set_optimizations (fiasco_c_options_t *options,
+					unsigned min_block_level,
+					unsigned max_block_level,
+					unsigned max_elements,
+					unsigned dictionary_size,
+					unsigned optimization_level);
+
+/* Set minimum and maximum size of image block prediction */
+int fiasco_c_options_set_prediction (fiasco_c_options_t *options,
+				     int intra_prediction,
+				     unsigned min_block_level,
+				     unsigned max_block_level);
+
+/*  Set various parameters used for video compensation */
+int fiasco_c_options_set_video_param (fiasco_c_options_t *options,
+				      unsigned frames_per_second,
+				      int half_pixel_prediction,
+				      int cross_B_search,
+				      int B_as_past_ref);
+
+/* Set accuracy of coefficients quantization */
+int fiasco_c_options_set_quantization (fiasco_c_options_t *options,
+				       unsigned mantissa,
+				       fiasco_rpf_range_e range,
+				       unsigned dc_mantissa,
+				       fiasco_rpf_range_e dc_range);
+
+/* Set type of progress meter */
+int fiasco_c_options_set_progress_meter (fiasco_c_options_t *options,
+					 fiasco_progress_e type);
+
+/*  Set comment of FIASCO stream */
+int fiasco_c_options_set_comment (fiasco_c_options_t *options,
+				  const char *comment);
+
+/*  Set title of FIASCO stream */
+int fiasco_c_options_set_title (fiasco_c_options_t *options,
+				const char *title);
+
+/****************************************************************************
+		 decoder options functions
+****************************************************************************/
+
+/* FIASCO additional options constructor */
+fiasco_d_options_t *fiasco_d_options_new (void);
+
+/* FIASCO additional options destructor */
+void fiasco_d_options_delete (fiasco_d_options_t *options);
+
+
+/* Define `smoothing'-percentage along partitioning borders.*/
+int fiasco_d_options_set_smoothing (fiasco_d_options_t *options,
+				  int smoothing);
+
+/* Set magnification-'level' of decoded image */
+int fiasco_d_options_set_magnification (fiasco_d_options_t *options,
+				      int level);
+
+/* Set image format to 4:2:0 or 4:4:4 */
+int fiasco_d_options_set_4_2_0_format (fiasco_d_options_t *options,
+				     int format);
+
+__END_DECLS
+
+#endif /* not _FIASCO_H */
diff --git a/converter/other/fiasco/fiascotopnm.c b/converter/other/fiasco/fiascotopnm.c
new file mode 100644
index 00000000..6d8b6f7f
--- /dev/null
+++ b/converter/other/fiasco/fiascotopnm.c
@@ -0,0 +1,477 @@
+/*
+ *  dwfa.c:     Decoding of WFA-files
+ *
+ *  Written by:     Ullrich Hafner
+ *          Michael Unger
+ *      
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+ 
+/*
+ *  $Date: 2000/10/28 17:39:29 $
+ *  $Author: hafner $
+ *  $Revision: 5.7 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+#include "pnm.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "types.h"
+#include "macros.h"
+
+#include <getopt.h>
+
+#include "binerror.h"
+#include "misc.h"
+#include "params.h"
+#include "fiasco.h"
+
+#ifndef X_DISPLAY_MISSING
+
+#   include "display.h"
+#   include "buttons.h"
+
+static x11_info_t *xinfo = NULL;
+
+#endif /* not X_DISPLAY_MISSING */
+
+/*****************************************************************************
+
+                prototypes
+  
+*****************************************************************************/
+
+static int 
+checkargs (int argc, char **argv, bool_t *double_resolution, bool_t *panel,
+           int *fps, char **image_name, fiasco_d_options_t **options);
+static void
+video_decoder (const char *wfa_name, const char *image_name, bool_t panel,
+               bool_t double_resolution, int fps, fiasco_d_options_t *options);
+static void
+get_output_template (const char *image_name, const char *wfa_name,
+                     bool_t color, char **basename, char **suffix);
+
+#ifndef X_DISPLAY_MISSING
+
+static void
+show_stored_frames (unsigned char * const *frame_buffer, int last_frame,
+                    x11_info_t *xinfo, binfo_t *binfo, size_t size,
+                    unsigned frame_time);
+
+#endif /* not X_DISPLAY_MISSING */
+
+/*****************************************************************************
+
+                public code
+  
+*****************************************************************************/
+
+int 
+main (int argc, char **argv)
+{
+    char               *image_name        = NULL; /* output filename */
+    bool_t              double_resolution = NO; /* double resolution of image */
+    bool_t              panel             = NO; /* control panel */
+    int             fps               = -1; /* frame display rate */
+    fiasco_d_options_t *options           = NULL; /* additional coder options */
+    int                 last_arg;    /* last processed cmdline parameter */
+
+    init_error_handling (argv[0]);
+
+    last_arg = checkargs (argc, argv, &double_resolution, &panel, &fps,
+                          &image_name, &options);
+   
+    if (last_arg >= argc)
+        video_decoder ("-", image_name, panel, double_resolution, fps, options);
+    else
+        while (last_arg++ < argc)
+            video_decoder (argv [last_arg - 1], image_name, panel,
+                           double_resolution, fps, options);
+
+    return 0;
+}
+
+/*****************************************************************************
+
+                private code
+  
+*****************************************************************************/
+
+static param_t params [] =
+{
+#ifdef X_DISPLAY_MISSING
+    {"output", "FILE", 'o', PSTR, {0}, "-",
+     "Write raw PNM frame(s) to `%s'."},
+#else  /* not X_DISPLAY_MISSING */
+    {"output", "FILE", 'o', POSTR, {0}, NULL,
+     "Write raw PNM frame(s) to INPUT.ppm/pgm [or `%s']."},
+#endif /* not X_DISPLAY_MISSING */
+    {"double", NULL, 'd', PFLAG, {0}, "FALSE",
+     "Interpolate images to double size before display."},
+    {"fast", NULL, 'r', PFLAG, {0}, "FALSE",
+     "Use 4:2:0 format for fast, low quality output."},
+    {"panel", NULL, 'p', PFLAG, {0}, "FALSE",
+     "Display control panel."},
+    {"magnify", "NUM", 'm', PINT, {0}, "0",
+     "Magnify/reduce image size by a factor of 4^`%s'."},
+    {"framerate", "NUM", 'F', PINT, {0}, "-1",
+     "Set display rate to `%s' frames per second."},
+    {"smoothing", "NUM", 's', PINT, {0}, "-1",
+     "Smooth image(s) by factor `%s' (0-100)"},
+    {NULL, NULL, 0, 0, {0}, NULL, NULL }
+};
+
+static int 
+checkargs (int argc, char **argv, bool_t *double_resolution, bool_t *panel,
+           int *fps, char **image_name, fiasco_d_options_t **options)
+/*
+ *  Check validness of command line parameters and of the parameter files.
+ *
+ *  Return value.
+ *  index in argv of the first argv-element that is not an option.
+ *
+ *  Side effects:
+ *  'double_resolution', 'panel', 'fps', 'image_name' and 'options'
+ *      are modified.
+ */
+{
+    int optind;              /* last processed commandline param */
+
+    optind = parseargs (params, argc, argv,
+#ifdef X_DISPLAY_MISSING
+                        "Decode FIASCO-FILEs and write frame(s) to disk.",
+#else  /* not X_DISPLAY_MISSING */
+                        "Decode and display FIASCO-FILEs using X11.",
+#endif /* not X_DISPLAY_MISSING */
+                        "With no FIASCO-FILE, or if FIASCO-FILE is -, "
+                        "read standard input.\n"
+#ifndef X_DISPLAY_MISSING
+                        "With --output=[FILE] specified, "
+                        "write frames without displaying them.\n\n"
+#endif  /* not X_DISPLAY_MISSING */
+                        "Environment:\n"
+                        "FIASCO_DATA   Search path for automata files. "
+                        "Default: ./\n"
+                        "FIASCO_IMAGES Save path for image files. "
+                        "Default: ./", " [FIASCO-FILE]...",
+                        FIASCO_SHARE, "system.fiascorc", ".fiascorc");
+
+    *image_name        =   (char *)   parameter_value (params, "output");
+    *double_resolution = *((bool_t *) parameter_value (params, "double"));
+    *panel             = *((bool_t *) parameter_value (params, "panel"));
+    *fps           = *((int *)    parameter_value (params, "framerate"));
+
+    /*
+     *  Additional options ... (have to be set with the fiasco_set_... methods)
+     */
+    *options = fiasco_d_options_new ();
+
+    {
+        int n = *((int *) parameter_value (params, "smoothing"));
+      
+        if (!fiasco_d_options_set_smoothing (*options, max (-1, n)))
+            error (fiasco_get_error_message ());
+    }
+
+    {
+        int n = *((int *) parameter_value (params, "magnify"));
+      
+        if (!fiasco_d_options_set_magnification (*options, n))
+            error (fiasco_get_error_message ());
+    }
+   
+    {
+        bool_t n = *((bool_t *) parameter_value (params, "fast"));
+      
+        if (!fiasco_d_options_set_4_2_0_format (*options, n > 0 ? YES : NO))
+            error (fiasco_get_error_message ());
+    }
+
+    return optind;
+}
+
+static void
+video_decoder (const char *wfa_name, const char *image_name, bool_t panel,
+               bool_t double_resolution, int fps, fiasco_d_options_t *options)
+{
+#ifndef X_DISPLAY_MISSING
+    fiasco_renderer_t  *renderer     = NULL;
+    unsigned char     **frame_buffer = NULL;
+    binfo_t            *binfo        = NULL; /* buttons info */
+#endif /* not X_DISPLAY_MISSING */
+   
+    do
+    {
+        unsigned      width, height, frames, n;
+        fiasco_decoder_t *decoder_state;
+        char             *filename;
+        char             *basename;   /* basename of decoded frame */
+        char             *suffix;     /* suffix of decoded frame */
+        unsigned      frame_time;
+      
+        if (!(decoder_state = fiasco_decoder_new (wfa_name, options)))
+            error (fiasco_get_error_message ());
+   
+        if (fps <= 0)         /* then use value of FIASCO file */ 
+            fps = fiasco_decoder_get_rate (decoder_state);
+        frame_time = fps ? (1000 / fps) : (1000 / 25);
+
+        if (!(width = fiasco_decoder_get_width (decoder_state)))
+            error (fiasco_get_error_message ());
+      
+        if (!(height = fiasco_decoder_get_height (decoder_state)))
+            error (fiasco_get_error_message ());
+
+        if (!(frames = fiasco_decoder_get_length (decoder_state)))
+            error (fiasco_get_error_message ());
+      
+        get_output_template (image_name, wfa_name,
+                             fiasco_decoder_is_color (decoder_state),
+                             &basename, &suffix);
+
+        filename = calloc (strlen (basename) + strlen (suffix) + 2
+                           + 10 + (int) (log10 (frames) + 1), sizeof (char));
+        if (!filename)
+            error ("Out of memory.");
+
+        for (n = 0; n < frames; n++)
+        {
+            clock_t fps_timer;     /* frames per second timer struct */
+     
+            prg_timer (&fps_timer, START);
+     
+            if (image_name)        /* just write frame to disk */
+            {
+                if (frames == 1)        /* just one image */
+                {
+                    if (streq (image_name, "-"))
+                        strcpy (filename, "-");
+                    else
+                        sprintf (filename, "%s.%s", basename, suffix);
+                }
+                else
+                {
+                    fprintf (stderr, "Decoding frame %d to file `%s.%0*d.%s\n",
+                             n, basename, (int) (log10 (frames - 1) + 1),
+                             n, suffix);
+                    sprintf (filename, "%s.%0*d.%s", basename,
+                             (int) (log10 (frames - 1) + 1), n, suffix);
+                }
+
+                if (!fiasco_decoder_write_frame (decoder_state, filename))
+                    error (fiasco_get_error_message ());
+            }
+#ifndef X_DISPLAY_MISSING
+            else
+            {
+                fiasco_image_t *frame;
+        
+                if (!(frame = fiasco_decoder_get_frame (decoder_state)))
+                    error (fiasco_get_error_message ());
+        
+                if (frames == 1)
+                    panel = NO;
+
+                if (xinfo == NULL)      /* initialize X11 window */
+                {
+                    const char * const title = 
+                        fiasco_decoder_get_title (decoder_state);
+                    char        titlename [MAXSTRLEN];
+
+           
+                    sprintf (titlename, "dfiasco " VERSION ": %s",
+                             strlen (title) > 0 ? title : wfa_name);
+                    xinfo = 
+                        open_window (titlename, "dfiasco",
+                                     (width  << (double_resolution ? 1 : 0)),
+                                     (height << (double_resolution ? 1 : 0))
+                                     + (panel ? 30 : 0));
+                    alloc_ximage (xinfo, width  << (double_resolution ? 1 : 0),
+                                  height << (double_resolution ? 1 : 0));
+                    if (panel)       /* initialize button panel */
+                        binfo = init_buttons (xinfo, n, frames, 30, 10);
+                    renderer = 
+                        fiasco_renderer_new (xinfo->ximage->red_mask,
+                                             xinfo->ximage->green_mask,
+                                             xinfo->ximage->blue_mask,
+                                             xinfo->ximage->bits_per_pixel,
+                                             double_resolution);
+                    if (!renderer)
+                        error (fiasco_get_error_message ());
+                }
+                renderer->render (renderer, xinfo->pixels, frame);
+                frame->delete (frame);
+        
+                if (frame_buffer != NULL) /* store next frame */
+                {
+                    size_t size = (width  << (double_resolution ? 1 : 0))
+                        * (height << (double_resolution ? 1 : 0))
+                        * (xinfo->ximage->depth <= 8
+                           ? sizeof (byte_t)
+                           : (xinfo->ximage->depth <= 16
+                              ? sizeof (u_word_t)
+                              : sizeof (unsigned int)));
+
+                    frame_buffer [n] = malloc (size);
+                    if (!frame_buffer [n])
+                        error ("Out of memory.");
+                    memcpy (frame_buffer [n], xinfo->pixels, size);
+
+                    if (n == frames - 1)
+                    {
+                        show_stored_frames (frame_buffer, frames - 1,
+                                            xinfo, binfo, size, frame_time);
+                        break;
+                    }
+                }
+
+                display_image (0, 0, xinfo);
+                if (frames == 1)
+                    wait_for_input (xinfo);
+                else if (panel)
+                {
+                    check_events (xinfo, binfo, n, frames);
+                    if (binfo->pressed [QUIT_BUTTON]) 
+                        /* start from beginning */
+                        break;
+                    if (binfo->pressed [STOP_BUTTON]) 
+                        /* start from beginning */
+                        n = frames;
+           
+                    if (binfo->pressed [RECORD_BUTTON] && frame_buffer == NULL)
+                    {
+                        n = frames;
+                        frame_buffer = 
+                            calloc (frames, sizeof (unsigned char *));
+                        if (!frame_buffer)
+                            error ("Out of memory.");
+                    }
+                }
+                while (prg_timer (&fps_timer, STOP) < frame_time) /* wait */
+                    ;
+            }
+#endif /* not X_DISPLAY_MISSING */   
+        }
+        free (filename);
+   
+        fiasco_decoder_delete (decoder_state);
+    } while (panel
+
+#ifndef X_DISPLAY_MISSING
+             && !binfo->pressed [QUIT_BUTTON]
+#endif /* not X_DISPLAY_MISSING */
+        
+        );
+
+#ifndef X_DISPLAY_MISSING
+    if (renderer)
+        renderer->delete (renderer);
+
+    if (!image_name)
+    {
+        close_window (xinfo);
+        free (xinfo);
+        xinfo = NULL;
+        if (binfo)
+            free (binfo);
+    }
+#endif /* not X_DISPLAY_MISSING */
+}
+
+static void
+get_output_template (const char *image_name, const char *wfa_name,
+                     bool_t color, char **basename, char **suffix)
+/*
+ *  Generate image filename template for output of image sequences.
+ *  'wfa_name' is the filename of the WFA stream.
+ *  Images are either saved with filename 'basename'.'suffix' (still images)
+ *  or 'basename'.%03d.'suffix' (videos).
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *  '*basename' and '*suffix' is set.
+ */
+{
+    if (!wfa_name || streq (wfa_name, "-"))
+        wfa_name = "stdin";       
+    /*
+     *  Generate filename template
+     */
+    if (!image_name || streq (image_name, "") || streq (image_name, "-"))
+    {
+        *basename = strdup (wfa_name);
+        *suffix   = NULL;
+    }
+    else
+    {
+        *basename = strdup (image_name);
+        *suffix   = strrchr (*basename, '.');
+    }
+    
+    if (*suffix)         /* found name 'basename.suffix' */
+    {
+        **suffix = 0;         /* remove dot */
+        (*suffix)++;
+        if (**suffix == 0)
+            *suffix = strdup (color ? "ppm" : "pgm");
+    }
+    else             /* no suffix found, generate one */
+        *suffix = strdup (color ? "ppm" : "pgm");
+}
+
+#ifndef X_DISPLAY_MISSING
+
+static void
+show_stored_frames (unsigned char * const *frame_buffer, int last_frame,
+                    x11_info_t *xinfo, binfo_t *binfo, size_t size,
+                    unsigned frame_time)
+/*
+ *  After a WFA video stream has been saved, all frames have been
+ *  decoded and stored in memory. These frames are then displayed
+ *  in an endless loop.
+ *
+ *  This function never returns, the program is terminated if the
+ *  STOP button is pressed.
+ */
+{
+    int n = last_frame;          /* frame number */
+   
+    while (1)
+    {
+        clock_t fps_timer;        /* frames per second timer struct */
+      
+        prg_timer (&fps_timer, START);
+      
+        display_image (0, 0, xinfo);
+        check_events (xinfo, binfo, n, last_frame + 1);
+
+        if (binfo->pressed [STOP_BUTTON])
+            n = 0;
+        else if (binfo->pressed [QUIT_BUTTON])
+            break;
+        else if (binfo->pressed [PLAY_BUTTON])
+            n++;
+        else if (binfo->pressed [RECORD_BUTTON]) /* REWIND is mapped RECORD */
+            n--;
+        if (n < 0)
+            n = last_frame;
+        if (n > last_frame)
+            n = 0;
+
+        memcpy (xinfo->pixels, frame_buffer [n], size);
+        while (prg_timer (&fps_timer, STOP) < frame_time) /* wait */
+            ;
+    };
+}
+
+#endif /* not X_DISPLAY_MISSING */
diff --git a/converter/other/fiasco/getopt.c b/converter/other/fiasco/getopt.c
new file mode 100644
index 00000000..0b2d1b75
--- /dev/null
+++ b/converter/other/fiasco/getopt.c
@@ -0,0 +1,1002 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
+   Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef	__GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#include <unistd.h>
+#endif	/* GNU C library.  */
+
+#ifdef VMS
+#include <unixlib.h>
+#if HAVE_STRING_H - 0
+#include <string.h>
+#endif
+#endif
+
+#if defined (WIN32) && !defined (__CYGWIN32__)
+/* It's not Unix, really.  See?  Capital letters.  */
+#include <windows.h>
+#define getpid() GetCurrentProcessId()
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+   When compiling libc, the _ macro is predefined.  */
+#ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid)	gettext (msgid)
+#else
+# define _(msgid)	(msgid)
+#endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+
+#ifdef	__GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define	my_index	strchr
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+	return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+#if !defined (__STDC__) || !__STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+static const char *nonoption_flags;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void store_args (int argc, char *const *argv) __attribute__ ((unused));
+static void
+store_args (int argc, char *const *argv)
+{
+  /* XXX This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+text_set_element (__libc_subinit, store_args);
+#endif
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined (__STDC__) && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+	{
+	  /* Bottom segment is the short one.  */
+	  int len = middle - bottom;
+	  register int i;
+
+	  /* Swap it with the top part of the top segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[top - (middle - bottom) + i];
+	      argv[top - (middle - bottom) + i] = tem;
+	    }
+	  /* Exclude the moved bottom segment from further swapping.  */
+	  top -= len;
+	}
+      else
+	{
+	  /* Top segment is the short one.  */
+	  int len = top - middle;
+	  register int i;
+
+	  /* Swap it with the bottom part of the bottom segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[middle + i];
+	      argv[middle + i] = tem;
+	    }
+	  /* Exclude the moved top segment from further swapping.  */
+	  bottom += len;
+	}
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined (__STDC__) && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind = 1;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#ifdef _LIBC
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      /* Bash 2.0 puts a special variable in the environment for each
+	 command it runs, specifying which ARGV elements are the results of
+	 file name wildcard expansion and therefore should not be
+	 considered as options.  */
+      char var[100];
+      sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ());
+      nonoption_flags = getenv (var);
+      if (nonoption_flags == NULL)
+	nonoption_flags_len = 0;
+      else
+	nonoption_flags_len = strlen (nonoption_flags);
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  optarg = NULL;
+
+  if (!__getopt_initialized || optind == 0)
+    {
+      optstring = _getopt_initialize (argc, argv, optstring);
+      optind = 1;		/* Don't scan ARGV[0], the program name.  */
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#ifdef _LIBC
+#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
+		     || (optind < nonoption_flags_len			      \
+			 && nonoption_flags[optind] == '1'))
+#else
+#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+	 moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+	last_nonopt = optind;
+      if (first_nonopt > optind)
+	first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+	{
+	  /* If we have just processed some options following some non-options,
+	     exchange them so that the options come first.  */
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (last_nonopt != optind)
+	    first_nonopt = optind;
+
+	  /* Skip any additional non-options
+	     and extend the range of non-options previously skipped.  */
+
+	  while (optind < argc && NONOPTION_P)
+	    optind++;
+	  last_nonopt = optind;
+	}
+
+      /* The special ARGV-element `--' means premature end of options.
+	 Skip it like a null option,
+	 then exchange with previous non-options as if it were an option,
+	 then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+	{
+	  optind++;
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (first_nonopt == last_nonopt)
+	    first_nonopt = optind;
+	  last_nonopt = argc;
+
+	  optind = argc;
+	}
+
+      /* If we have done all the ARGV-elements, stop the scan
+	 and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+	{
+	  /* Set the next-arg-index to point at the non-options
+	     that we previously skipped, so the caller will digest them.  */
+	  if (first_nonopt != last_nonopt)
+	    optind = first_nonopt;
+	  return -1;
+	}
+
+      /* If we have come to a non-option and did not permute it,
+	 either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+	{
+	  if (ordering == REQUIRE_ORDER)
+	    return -1;
+	  optarg = argv[optind++];
+	  return 1;
+	}
+
+      /* We have found another option-ARGV-element.
+	 Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+		  + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+	/* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+	 or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	if (!strncmp (p->name, nextchar, nameend - nextchar))
+	  {
+	    if ((unsigned int) (nameend - nextchar)
+		== (unsigned int) strlen (p->name))
+	      {
+		/* Exact match found.  */
+		pfound = p;
+		indfound = option_index;
+		exact = 1;
+		break;
+	      }
+	    else if (pfound == NULL)
+	      {
+		/* First nonexact match found.  */
+		pfound = p;
+		indfound = option_index;
+	      }
+	    else
+	      /* Second or later nonexact match found.  */
+	      ambig = 1;
+	  }
+
+      if (ambig && !exact)
+	{
+	  if (opterr)
+	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+		     argv[0], argv[optind]);
+	  nextchar += strlen (nextchar);
+	  optind++;
+	  optopt = 0;
+	  return '?';
+	}
+
+      if (pfound != NULL)
+	{
+	  option_index = indfound;
+	  optind++;
+	  if (*nameend)
+	    {
+	      /* Don't test has_arg with >, because some C compilers don't
+		 allow it to be used on enums.  */
+	      if (pfound->has_arg)
+		optarg = nameend + 1;
+	      else
+		{
+            if (opterr) {
+		   if (argv[optind - 1][1] == '-')
+		    /* --option */
+		    fprintf (stderr,
+		     _("%s: option `--%s' doesn't allow an argument\n"),
+		     argv[0], pfound->name);
+		   else
+		    /* +option or -option */
+		    fprintf (stderr,
+		     _("%s: option `%c%s' doesn't allow an argument\n"),
+		     argv[0], argv[optind - 1][0], pfound->name);
+            }
+
+		  nextchar += strlen (nextchar);
+
+		  optopt = pfound->val;
+		  return '?';
+		}
+	    }
+	  else if (pfound->has_arg == 1)
+	    {
+	      if (optind < argc)
+		optarg = argv[optind++];
+	      else
+		{
+		  if (opterr)
+		    fprintf (stderr,
+			   _("%s: option `%s' requires an argument\n"),
+			   argv[0], argv[optind - 1]);
+		  nextchar += strlen (nextchar);
+		  optopt = pfound->val;
+		  return optstring[0] == ':' ? ':' : '?';
+		}
+	    }
+	  nextchar += strlen (nextchar);
+	  if (longind != NULL)
+	    *longind = option_index;
+	  if (pfound->flag)
+	    {
+	      *(pfound->flag) = pfound->val;
+	      return 0;
+	    }
+	  return pfound->val;
+	}
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+	 or the option starts with '--' or is not a valid short
+	 option, then it's an error.
+	 Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+	  || my_index (optstring, *nextchar) == NULL)
+	{
+	  if (opterr)
+	    {
+	      if (argv[optind][1] == '-')
+		/* --option */
+		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+			 argv[0], nextchar);
+	      else
+		/* +option or -option */
+		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+			 argv[0], argv[optind][0], nextchar);
+	    }
+	  nextchar = (char *) "";
+	  optind++;
+	  optopt = 0;
+	  return '?';
+	}
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+	if (opterr)
+	  {
+	    if (posixly_correct)
+	      /* 1003.2 specifies the format of this message.  */
+	      fprintf (stderr, _("%s: illegal option -- %c\n"),
+		       argv[0], c);
+	    else
+	      fprintf (stderr, _("%s: invalid option -- %c\n"),
+		       argv[0], c);
+	  }
+	optopt = c;
+	return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+	char *nameend;
+	const struct option *p;
+	const struct option *pfound = NULL;
+	int exact = 0;
+	int ambig = 0;
+	int indfound = 0;
+	int option_index;
+
+	/* This is an option that requires an argument.  */
+	if (*nextchar != '\0')
+	  {
+	    optarg = nextchar;
+	    /* If we end this ARGV-element by taking the rest as an arg,
+	       we must advance to the next element now.  */
+	    optind++;
+	  }
+	else if (optind == argc)
+	  {
+	    if (opterr)
+	      {
+		/* 1003.2 specifies the format of this message.  */
+		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+			 argv[0], c);
+	      }
+	    optopt = c;
+	    if (optstring[0] == ':')
+	      c = ':';
+	    else
+	      c = '?';
+	    return c;
+	  }
+	else
+	  /* We already incremented `optind' once;
+	     increment it again when taking next ARGV-elt as argument.  */
+	  optarg = argv[optind++];
+
+	/* optarg is now the argument, see if it's in the
+	   table of longopts.  */
+
+	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+	  /* Do nothing.  */ ;
+
+	/* Test all long options for either exact match
+	   or abbreviated matches.  */
+	for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	  if (!strncmp (p->name, nextchar, nameend - nextchar))
+	    {
+	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+		{
+		  /* Exact match found.  */
+		  pfound = p;
+		  indfound = option_index;
+		  exact = 1;
+		  break;
+		}
+	      else if (pfound == NULL)
+		{
+		  /* First nonexact match found.  */
+		  pfound = p;
+		  indfound = option_index;
+		}
+	      else
+		/* Second or later nonexact match found.  */
+		ambig = 1;
+	    }
+	if (ambig && !exact)
+	  {
+	    if (opterr)
+	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+		       argv[0], argv[optind]);
+	    nextchar += strlen (nextchar);
+	    optind++;
+	    return '?';
+	  }
+	if (pfound != NULL)
+	  {
+	    option_index = indfound;
+	    if (*nameend)
+	      {
+		/* Don't test has_arg with >, because some C compilers don't
+		   allow it to be used on enums.  */
+		if (pfound->has_arg)
+		  optarg = nameend + 1;
+		else
+		  {
+		    if (opterr)
+		      fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+			       argv[0], pfound->name);
+
+		    nextchar += strlen (nextchar);
+		    return '?';
+		  }
+	      }
+	    else if (pfound->has_arg == 1)
+	      {
+		if (optind < argc)
+		  optarg = argv[optind++];
+		else
+		  {
+		    if (opterr)
+		      fprintf (stderr,
+			       _("%s: option `%s' requires an argument\n"),
+			       argv[0], argv[optind - 1]);
+		    nextchar += strlen (nextchar);
+		    return optstring[0] == ':' ? ':' : '?';
+		  }
+	      }
+	    nextchar += strlen (nextchar);
+	    if (longind != NULL)
+	      *longind = option_index;
+	    if (pfound->flag)
+	      {
+		*(pfound->flag) = pfound->val;
+		return 0;
+	      }
+	    return pfound->val;
+	  }
+	  nextchar = NULL;
+	  return 'W';	/* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+	if (temp[2] == ':')
+	  {
+	    /* This is an option that accepts an argument optionally.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		optind++;
+	      }
+	    else
+	      optarg = NULL;
+	    nextchar = NULL;
+	  }
+	else
+	  {
+	    /* This is an option that requires an argument.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		/* If we end this ARGV-element by taking the rest as an arg,
+		   we must advance to the next element now.  */
+		optind++;
+	      }
+	    else if (optind == argc)
+	      {
+		if (opterr)
+		  {
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr,
+			   _("%s: option requires an argument -- %c\n"),
+			   argv[0], c);
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = '?';
+	      }
+	    else
+	      /* We already incremented `optind' once;
+		 increment it again when taking next ARGV-elt as argument.  */
+	      optarg = argv[optind++];
+	    nextchar = NULL;
+	  }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+			   (const struct option *) 0,
+			   (int *) 0,
+			   0);
+}
+
+#endif	/* Not ELIDE_CODE.  */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/converter/other/fiasco/getopt.h b/converter/other/fiasco/getopt.h
new file mode 100644
index 00000000..9acca708
--- /dev/null
+++ b/converter/other/fiasco/getopt.h
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+   Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+  const char *name;
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/converter/other/fiasco/getopt1.c b/converter/other/fiasco/getopt1.c
new file mode 100644
index 00000000..8347bb13
--- /dev/null
+++ b/converter/other/fiasco/getopt1.c
@@ -0,0 +1,189 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef	NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif	/* Not ELIDE_CODE.  */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+	{"add", 1, 0, 0},
+	{"append", 0, 0, 0},
+	{"delete", 1, 0, 0},
+	{"verbose", 0, 0, 0},
+	{"create", 0, 0, 0},
+	{"file", 1, 0, 0},
+	{0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+		       long_options, &option_index);
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case 0:
+	  printf ("option %s", long_options[option_index].name);
+	  if (optarg)
+	    printf (" with arg %s", optarg);
+	  printf ("\n");
+	  break;
+
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case 'd':
+	  printf ("option d with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/converter/other/fiasco/input/Makefile b/converter/other/fiasco/input/Makefile
new file mode 100644
index 00000000..c01af772
--- /dev/null
+++ b/converter/other/fiasco/input/Makefile
@@ -0,0 +1,26 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/../../../..
+  BUILDDIR = $(SRCDIR)
+endif
+FIASCOSUBDIR = converter/other/fiasco
+SUBDIR = $(FIASCOSUBDIR)/input
+BUILDDIR = ../../../..
+VPATH=.:$(SRCDIR)/$(SUBDIR)
+
+include $(BUILDDIR)/Makefile.config
+
+OBJECTS =  basis.o matrices.o mc.o nd.o read.o tree.o weights.o
+
+MERGE_OBJECTS = $(OBJECTS)
+
+INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR) -I$(SRCDIR)/$(FIASCOSUBDIR)/lib \
+	   -I$(SRCDIR)/$(FIASCOSUBDIR)/codec
+
+all: libfiasco_input.a
+
+include $(SRCDIR)/Makefile.common
+
+libfiasco_input.a: $(OBJECTS)
+	$(AR) -rc $@ $(OBJECTS)
+	$(RANLIB) $@
+
diff --git a/converter/other/fiasco/input/basis.c b/converter/other/fiasco/input/basis.c
new file mode 100644
index 00000000..cef075e6
--- /dev/null
+++ b/converter/other/fiasco/input/basis.c
@@ -0,0 +1,141 @@
+/*
+ *  basis.c:		WFA initial basis files	
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/25 16:38:06 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "wfalib.h"
+
+#include "basis.h"
+
+typedef struct basis_values
+{
+   unsigned  states;
+   real_t   *final;
+   bool_t   *use_domain;
+   real_t (*transitions)[4];
+} basis_values_t;
+
+typedef struct
+{
+    const char *filename;
+    void (*function)(basis_values_t *bv);
+} basis_file_t;
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+small_init (basis_values_t *bv);
+
+static basis_file_t const basis_files[] = { 
+    {"small.fco", small_init},
+    {"small.wfa", small_init},
+    {NULL, NULL} 
+};
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+bool_t
+get_linked_basis (const char *basis_name, wfa_t *wfa)
+/*
+ *  Check wether given WFA initial basis 'basis_name' is already linked
+ *  with the excecutable. If the basis is available then fill the 'wfa' struct
+ *  according to the stored data, otherwise print a warning message.
+ *
+ *  Return value:
+ *	true on success, false if basis is not available yet.
+ *
+ *  Side effects:
+ *	'wfa' struct is filled on success.
+ */
+{
+   bool_t	  success = NO;		/* indicates if basis is found */
+   unsigned	  n;			/* counter */
+   basis_values_t bv;			/* basis values */
+   
+   for (n = 0; basis_files [n].filename != NULL; n++)
+      if (streq (basis_files [n].filename, basis_name))	/* basis is stored */
+      {
+	 unsigned state, edge;		
+	 
+	 (*basis_files [n].function) (&bv); /* initialize local variables */
+	 /*
+	  *  Generate WFA
+	  */
+	 wfa->basis_states = wfa->states = bv.states + 1;
+	 wfa->domain_type[0]             = USE_DOMAIN_MASK; 
+	 wfa->final_distribution[0]      = 128;
+	 append_edge (0, 0, 1.0, 0, wfa);
+	 append_edge (0, 0, 1.0, 1, wfa);
+	 for (state = 1; state < wfa->basis_states; state++)
+	 {
+	    wfa->final_distribution [state] = bv.final [state - 1];
+	    wfa->domain_type [state]        = bv.use_domain [state - 1]
+					      ? USE_DOMAIN_MASK
+					      : AUXILIARY_MASK;
+	 }
+	 for (edge = 0; isedge (bv.transitions [edge][0]); edge++)
+	    append_edge (bv.transitions [edge][0], bv.transitions [edge][1],
+			 bv.transitions [edge][2], bv.transitions [edge][3],
+			 wfa);
+	 
+	 success = YES;
+	 break;
+      }
+
+   if (!success)
+      warning ("WFA initial basis '%s' isn't linked with the excecutable yet."
+	       "\nLoading basis from disk instead.", basis_name);
+
+   return success;
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+/*****************************************************************************
+				basis "small.wfa"
+*****************************************************************************/
+
+static unsigned	states_small           = 2;
+static bool_t	use_domain_small[]     = {YES, YES};
+static real_t 	final_small[]          = {64, 64};
+static real_t 	transitions_small[][4] = {{1, 2, 0.5, 0}, {1, 2, 0.5, 1},
+				      	 {1, 0, 0.5, 1}, {2, 1, 1.0, 0},
+				      	 {2, 1, 1.0, 1}, {-1, 0, 0, 0}};
+static void
+small_init (basis_values_t *bv)
+{
+   bv->states      = states_small;
+   bv->final       = final_small;
+   bv->use_domain  = use_domain_small;
+   bv->transitions = transitions_small;
+}
diff --git a/converter/other/fiasco/input/basis.h b/converter/other/fiasco/input/basis.h
new file mode 100644
index 00000000..fa26bca2
--- /dev/null
+++ b/converter/other/fiasco/input/basis.h
@@ -0,0 +1,26 @@
+/*
+ *  basis.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _BASIS_H
+#define _BASIS_H
+
+#include "wfa.h"
+
+bool_t
+get_linked_basis (const char *basis_name, wfa_t *wfa);
+
+#endif /* not _BASIS_H */
+
diff --git a/converter/other/fiasco/input/matrices.c b/converter/other/fiasco/input/matrices.c
new file mode 100644
index 00000000..47cde1aa
--- /dev/null
+++ b/converter/other/fiasco/input/matrices.c
@@ -0,0 +1,644 @@
+/*
+ *  matrices.c:		Input of transition matrices
+ *
+ *  Written by:		Ullrich Hafner
+ *  
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "bit-io.h"
+#include "arith.h"
+#include "misc.h"
+#include "wfalib.h"
+
+#include "matrices.h"
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static unsigned
+delta_decoding (wfa_t *wfa, unsigned last_domain, bitfile_t *input);
+static unsigned
+column_0_decoding (wfa_t *wfa, unsigned last_row, bitfile_t *input);
+static unsigned
+chroma_decoding (wfa_t *wfa, bitfile_t *input);
+static void
+compute_y_state (int state, int y_state, wfa_t *wfa);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+unsigned
+read_matrices (wfa_t *wfa, bitfile_t *input)
+/* 
+ *  Read transitions of WFA given from the stream 'input'.
+ *
+ *  Return value:
+ *	number of edges
+ *
+ *  Side effects:
+ *	'wfa->into' is filled with decoded values 
+ */
+{
+   unsigned total;			/* total number of edges in the WFA */
+   unsigned root_state = wfa->wfainfo->color
+			 ? wfa->tree [wfa->tree [wfa->root_state][0]][0]
+			 : wfa->root_state;
+
+   total  = column_0_decoding (wfa, root_state, input);
+   total += delta_decoding (wfa, root_state, input);
+   if (wfa->wfainfo->color)
+      total += chroma_decoding (wfa, input);
+       
+   return total;
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static unsigned
+delta_decoding (wfa_t *wfa, unsigned last_domain, bitfile_t *input)
+/*
+ *  Read transition matrices which are encoded with delta coding
+ *  from stream 'input'.
+ *  'last_domain' is the maximum state number used as domain image.
+ *
+ *  Return value:
+ *	number of non-zero matrix elements (WFA edges)
+ *
+ *  Side effects:
+ *	'wfa->into' is filled with decoded values 
+ */
+{
+   range_sort_t	 rs;			/* ranges are sorted as in the coder */
+   unsigned	 max_domain;		/* dummy used for recursion */
+   unsigned	 range;
+   unsigned	 count [MAXEDGES + 1];
+   unsigned 	 state, label;
+   unsigned	*n_edges;		/* number of elements per row */
+   unsigned	 total = 0;		/* total number of decoded edges */
+
+   /*
+    *  Generate a list of range blocks.
+    *  The order is the same as in the coder.
+    */
+   rs.range_state      = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (u_word_t));
+   rs.range_label      = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (byte_t));
+   rs.range_max_domain = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (u_word_t));
+   rs.range_subdivided = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (bool_t));
+   rs.range_no	       = 0;
+   max_domain 	       = wfa->basis_states - 1;
+   sort_ranges (last_domain, &max_domain, &rs, wfa);
+
+   /*
+    *  Get row statistics
+    */
+   {
+      arith_t  *decoder;
+      model_t  *elements;
+      unsigned 	max_edges = read_rice_code (3, input);
+      
+      /*
+       *  Get the probability array of the number of edges distribution
+       *  and allocate the corresponding model.
+       */
+      {
+	 unsigned edge;
+	 
+	 for (edge = 0; edge <= max_edges; edge++)
+	    count [edge] = read_rice_code ((int) log2 (last_domain) - 2,
+					   input);
+	 elements = alloc_model (max_edges + 1, 0, 0, count);
+      }
+      
+      /*
+       *  Get number of elements per matrix row
+       */
+      {
+	 unsigned row;
+      
+	 n_edges = Calloc (wfa->states, sizeof (unsigned));
+	 decoder = alloc_decoder (input);
+	 for (row = range = 0; range < rs.range_no; range++)
+	    if (!rs.range_subdivided [range])
+	    {
+	       state = rs.range_state [range];
+	       label = rs.range_label [range];
+	       
+	       n_edges [row++]
+		  = decode_symbol (decoder, elements)
+		  - (isedge (wfa->into [state][label][0]) ? 1 : 0);
+	    }
+	 
+	 free_decoder (decoder);
+	 free_model (elements);
+      }
+   }
+   
+   /*
+    *  Get matrix elements
+    */
+   {
+      unsigned row;
+      u_word_t *mapping1           = Calloc (wfa->states, sizeof (word_t));
+      u_word_t *mapping_coder1     = Calloc (wfa->states, sizeof (word_t));
+      u_word_t *mapping2           = Calloc (wfa->states, sizeof (word_t));
+      u_word_t *mapping_coder2     = Calloc (wfa->states, sizeof (word_t));
+      bool_t	use_normal_domains = get_bit (input);
+      bool_t	use_delta_domains  = get_bit (input);
+	  
+      /*
+       *  Generate array of states which are admitted domains.
+       *  When coding intra frames 'mapping1' == 'mapping2' otherwise
+       *  'mapping1' is a list of 'normal' domains which are admitted for 
+       *             coding intra blocks
+       *  'mapping2' is a list of 'delta' domains which are admitted for
+       *             coding the motion compensated prediction error 
+       */
+      {
+	 unsigned n1, n2, state;
+	    
+	 for (n1 = n2 = state = 0; state < wfa->states; state++)
+	 {
+	    mapping1 [n1] = state;
+	    mapping_coder1 [state] = n1;
+	    if (usedomain (state, wfa)
+		&& (state < wfa->basis_states
+		    || use_delta_domains || !wfa->delta_state [state]))
+	       n1++;
+	    
+	    mapping2 [n2] = state;
+	    mapping_coder2 [state] = n2;
+	    if (usedomain (state, wfa)
+		&& (state < wfa->basis_states || use_normal_domains
+		    || wfa->delta_state [state]))
+	       n2++;
+	 }
+      }
+	 
+      for (row = 0, range = 0; range < rs.range_no; range++)
+	 if (!rs.range_subdivided [range])
+	 {
+	    u_word_t *mapping;
+	    u_word_t *mapping_coder;
+	    unsigned  max_value;
+	    unsigned  edge;
+	    unsigned  state = rs.range_state [range];
+	    unsigned  label = rs.range_label [range];
+	    unsigned  last  = 1;
+
+	    if (wfa->delta_state [state] ||
+		wfa->mv_tree [state][label].type != NONE)
+	    {
+	       mapping 	     = mapping2;
+	       mapping_coder = mapping_coder2;
+	    }
+	    else
+	    {
+	       mapping 	     = mapping1;
+	       mapping_coder = mapping_coder1;
+	    }
+	    max_value = mapping_coder [rs.range_max_domain [range]];
+	    for (edge = n_edges [row]; edge; edge--)
+	    {
+	       unsigned domain;
+
+	       if (max_value - last)
+		  domain = read_bin_code (max_value - last, input) + last;
+	       else
+		  domain = max_value;
+	       append_edge (state, mapping [domain], -1, label, wfa);
+	       last = domain + 1;
+	       total++;
+	    }
+	    row++;
+	 }
+      Free (mapping1);
+      Free (mapping_coder1);
+      Free (mapping2);
+      Free (mapping_coder2);
+   }
+      
+   Free (n_edges);
+   Free (rs.range_state);
+   Free (rs.range_label);
+   Free (rs.range_max_domain);
+   Free (rs.range_subdivided);
+
+   return total;
+}
+
+static unsigned
+column_0_decoding (wfa_t *wfa, unsigned last_row, bitfile_t *input)
+/*
+ *  Read column 0 of the transition matrices of the 'wfa' which are coded
+ *  with quasi arithmetic coding from stream 'input'.
+ *  All rows from 'wfa->basis_states' up to 'last_row' are decoded.
+ * 
+ *  Return value:
+ *	number of non-zero matrix elements (WFA edges)
+ *
+ *  Side effects:
+ *	'wfa->into' is filled with decoded values 
+ */
+{
+   unsigned  row;			/* current matrix row */
+   unsigned  total = 0;			/* total number of edges in col 0 */
+   unsigned *prob_ptr;			/* pointer to current probability */
+   unsigned *last;			/* pointer to minimum probability */
+   unsigned *first;			/* pointer to maximum probability */
+   unsigned *new_prob_ptr;		/* ptr to probability of last domain */
+   unsigned *prob;			/* probability array */
+   u_word_t  high;			/* Start of the current code range */
+   u_word_t  low;			/* End of the current code range */
+   u_word_t  code;			/* The present input code value */
+   word_t   *is_leaf;			/* pointer to the tree structure */
+
+   /*
+    *  Compute the asymmetric probability array
+    *  prob[] = { 1/2, 1/2, 1/4, 1/4, 1/4, 1/4,
+    *             1/8, ... , 1/16, ..., 1/(MAXPROB+1)}
+    */
+   {
+      unsigned n;
+      unsigned index;			/* probability index */
+      unsigned exp;			/* current exponent */
+      
+      prob = Calloc (1 << (MAX_PROB + 1), sizeof (unsigned));
+   
+      for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++)
+	 for (exp = 0; exp < 1U << n; exp++, index++)
+	    prob [index] = n;
+   }
+
+   first = prob_ptr = new_prob_ptr = prob;
+   last  = first + 1020;
+   
+   is_leaf = wfa->tree [wfa->basis_states]; /* use pointer arithmetics ... */
+
+   high = HIGH;				/* 1.0 */
+   low  = LOW;				/* 0.0 */
+   code = get_bits (input, 16);		
+
+   /*
+    *  Decode column 0 with a quasi arithmetic coder (QAC).
+    *  Advantage of this QAC with respect to a binary AC:
+    *  Instead of using time consuming multiplications and divisions
+    *  to compute the probability of the most probable symbol (MPS) and
+    *  the range of the interval, a table look up procedure linked
+    *  with a shift operation is used for both computations.
+    *
+    *  Loops and array accesses have been removed
+    *  to make real time decoding possible.
+    */
+   for (row = wfa->basis_states; row <= last_row; row++)
+   {
+      unsigned count;			/* value in the current interval */
+      
+      /*
+       *  Read label 0 element
+       */
+      if (isrange (*is_leaf++))		/* valid matrix index */
+      {
+	 count = high - ((high - low) >> *prob_ptr);
+	 if (code < count)
+	 {
+	    if (prob_ptr < last)	/* model update */
+	       prob_ptr++;
+	    /*
+	     *  Decode the MPS '0'
+	     */
+	    high = count - 1;
+
+	    RESCALE_INPUT_INTERVAL;
+	 }
+	 else
+	 {
+	    prob_ptr = ((prob_ptr - first) >> 1) + first; /* model update */
+	    /*
+	     *  Decode the LPS '1'
+	     */
+	    low = count;
+
+	    RESCALE_INPUT_INTERVAL;
+	    /*
+	     *  Restore the transition (weight = -1)
+	     */
+	    append_edge (row, 0, -1, 0, wfa);
+	    total++;
+	 }
+      }
+      /*
+       *  Read label 1 element
+       */
+      if (isrange (*is_leaf++)) /* valid matrix index */
+      {
+	 count = high - ((high - low) >> *prob_ptr);
+	 if (code < count)
+	 {
+	    if (prob_ptr < last)
+	       prob_ptr++;		/* model update */
+	    /*
+	     *  Decode the MPS '0'
+	     */
+	    high = count - 1;
+
+	    RESCALE_INPUT_INTERVAL;
+	 }
+	 else
+	 {
+	    prob_ptr = ((prob_ptr - first) >> 1) + first; /* model update */
+	    /*
+	     *  Decode the LPS '1'
+	     */
+	    low = count;
+
+	    RESCALE_INPUT_INTERVAL;
+	    /*
+	     *  Restore the transition (weight = -1)
+	     */
+	    append_edge (row, 0, -1, 1, wfa);
+	    total++;
+	 }
+      }
+   }
+
+   INPUT_BYTE_ALIGN (input);
+
+   Free (prob);
+   
+   return total;
+}
+
+static unsigned
+chroma_decoding (wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read transition matrices of 'wfa' states which are part of the
+ *  chroma channels Cb and Cr from stream 'input'.
+ *
+ *  Return value:
+ *	number of non-zero matrix elements (WFA edges)
+ *
+ *  Side effects:
+ *	'wfa->into' is filled with decoded values 
+ */
+{
+   unsigned  domain;			/* current domain, counter */
+   unsigned  total = 0;			/* total number of chroma edges */
+   unsigned *prob_ptr;			/* pointer to current probability */
+   unsigned *last;			/* pointer to minimum probability */
+   unsigned *first;			/* pointer to maximum probability */
+   unsigned *new_prob_ptr;		/* ptr to probability of last domain */
+   unsigned *prob;			/* probability array */
+   u_word_t  high;			/* Start of the current code range */
+   u_word_t  low;			/* End of the current code range */
+   u_word_t  code;			/* The present input code value */
+   word_t   *y_domains;			/* domain images corresponding to Y */
+   int	     save_index;		/* YES: store current probabilty */
+
+   /*
+    *  Compute the asymmetric probability array
+    *  prob[] = { 1/2, 1/2, 1/4, 1/4, 1/4, 1/4,
+    *                     1/8, ... , 1/16, ..., 1/(MAXPROB+1)}
+    */
+   {
+      unsigned n;
+      unsigned index;			/* probability index */
+      unsigned exp;			/* current exponent */
+      
+      prob = Calloc (1 << (MAX_PROB + 1), sizeof (unsigned));
+   
+      for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++)
+	 for (exp = 0; exp < 1U << n; exp++, index++)
+	    prob [index] = n;
+   }
+
+   high = HIGH;				/* 1.0 */
+   low  = LOW;				/* 0.0 */
+   code = get_bits (input, 16);
+
+   /*
+    *  Compute list of admitted domains
+    */
+   y_domains = compute_hits (wfa->basis_states,
+			     wfa->tree [wfa->tree [wfa->root_state][0]][0],
+			     wfa->wfainfo->chroma_max_states, wfa);
+   
+   first = prob_ptr = new_prob_ptr = prob;
+   last  = first + 1020;
+
+   /*
+    *  First of all, read all matrix columns given in the list 'y_domains'
+    *  which note all admitted domains.
+    *  These matrix elements are stored with QAC (see column_0_decoding ()).
+    */
+   for (domain = 0; y_domains [domain] != -1; domain++)
+   {
+      unsigned 	row	= wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1;
+      word_t   *is_leaf = wfa->tree [row];
+
+      prob_ptr   = new_prob_ptr;
+      save_index = YES;
+
+      for (; row < wfa->states; row++)
+      {
+	 unsigned count;		/* value in the current interval */
+	 /*
+	  *  Read label 0 element
+	  */
+	 if (isrange (*is_leaf++)) 	/* valid matrix index */
+	 {
+	    count = high - ((high - low) >> *prob_ptr);
+	    if (code < count)
+	    {
+	       if (prob_ptr < last)
+		  prob_ptr++;
+	       /*
+		*  Decode the MPS '0'
+		*/
+	       high = count - 1;
+
+	       RESCALE_INPUT_INTERVAL;
+	    }
+	    else
+	    {
+	       prob_ptr = ((prob_ptr - first) >> 1) + first;
+	       /*
+		*  Decode the LPS '1'
+		*/
+	       low = count;
+
+	       RESCALE_INPUT_INTERVAL;
+	       /*
+		*  Restore the transition (weight = -1)
+		*/
+	       append_edge (row, y_domains [domain], -1, 0, wfa);
+	       total++;
+	    }
+	 }
+	 /*
+	  *  Read label 1 element
+	  */
+	 if (isrange (*is_leaf++)) /* valid matrix index */
+	 {
+	    count = high - ((high - low) >> *prob_ptr);
+	    if (code < count)
+	    {
+	       if (prob_ptr < last)
+		  prob_ptr++;
+	       /*
+		*  Decode the MPS '0'
+		*/
+	       high = count - 1;
+
+	       RESCALE_INPUT_INTERVAL;
+	    }
+	    else
+	    {
+	       prob_ptr = ((prob_ptr - first) >> 1) + first;
+	       /*
+		*  Decode the LPS '1'
+		*/
+	       low = count;
+
+	       RESCALE_INPUT_INTERVAL;
+	       /*
+		*  Restore the transition (weight = -1)
+		*/
+	       append_edge (row, y_domains [domain], -1, 1, wfa);
+	       total++;
+	    }
+	 }
+	 if (save_index)
+	 {
+	    save_index 	 = NO;
+	    new_prob_ptr = prob_ptr;
+	 }
+      }
+   }
+
+   Free (y_domains);
+
+   compute_y_state (wfa->tree [wfa->tree [wfa->root_state][0]][1],
+		    wfa->tree [wfa->tree [wfa->root_state][0]][0], wfa);
+   compute_y_state (wfa->tree [wfa->tree [wfa->root_state][1]][0],
+		    wfa->tree [wfa->tree [wfa->root_state][0]][0], wfa);
+   
+   first = prob_ptr = new_prob_ptr = prob;
+
+   /*
+    *  Decode the additional column which indicates whether there
+    *  are transitions to a state with same spatial coordinates
+    *  in the Y component.
+    *
+    *  Again, quasi arithmetic decoding is used for this task.
+    */
+   {
+      unsigned 	row;
+      
+      for (row = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1;
+	   row < wfa->states; row++)
+      {
+	 int label;			/* current label */
+
+	 for (label = 0; label < MAXLABELS; label++)
+	 {
+	    u_word_t count = high - ((high - low) >> *prob_ptr);
+
+	    if (code < count)
+	    {
+	       if (prob_ptr < last)
+		  prob_ptr++;
+	       /*
+		*  Decode the MPS '0'
+		*/
+	       high = count - 1;
+
+	       RESCALE_INPUT_INTERVAL;
+	    }
+	    else
+	    {
+	       prob_ptr = ((prob_ptr - first) >> 1) + first;
+	       /*
+		*  Decode the LPS '1'
+		*/
+	       low = count;
+
+	       RESCALE_INPUT_INTERVAL;
+	       /*
+		*  Restore the transition (weight = -1)
+		*/
+	       append_edge (row, wfa->y_state [row][label], -1, label, wfa);
+	       total++;
+	    }
+	 }
+      }
+   }
+
+   INPUT_BYTE_ALIGN (input);
+
+   Free (prob);
+
+   return total;
+}
+
+static void
+compute_y_state (int state, int y_state, wfa_t *wfa)
+/*
+ *  Compute the 'wfa->y_state' array which denotes those states of
+ *  the Y band that have the same spatial coordinates as the corresponding
+ *  states of the Cb and Cr bands.
+ *  The current root of the Y tree is given by 'y_state'.
+ *  The current root of the tree of the chroma channel is given by 'state'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->y_state' is filled with the generated tree structure.
+ */
+{
+   unsigned label;
+   
+   for (label = 0; label < MAXLABELS; label++)
+      if (isrange (y_state))
+	 wfa->y_state [state][label] = RANGE;
+      else
+      {
+	 wfa->y_state [state][label] = wfa->tree [y_state][label];
+	 if (!isrange (wfa->tree [state][label]))
+	    compute_y_state (wfa->tree [state][label],
+			     wfa->y_state [state][label], wfa);
+      }
+      
+}
diff --git a/converter/other/fiasco/input/matrices.h b/converter/other/fiasco/input/matrices.h
new file mode 100644
index 00000000..ba8fd9bf
--- /dev/null
+++ b/converter/other/fiasco/input/matrices.h
@@ -0,0 +1,27 @@
+/*
+ *  matrices.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MATRICES_H
+#define _MATRICES_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+unsigned
+read_matrices (wfa_t *wfa, bitfile_t *input);
+
+#endif /* not _MATRICES_H */
+
diff --git a/converter/other/fiasco/input/mc.c b/converter/other/fiasco/input/mc.c
new file mode 100644
index 00000000..070d839e
--- /dev/null
+++ b/converter/other/fiasco/input/mc.c
@@ -0,0 +1,334 @@
+/*
+ *  mc.c:	Input of motion compensation	
+ *
+ *  written by: Michael Unger
+ *		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include <stdlib.h>
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "bit-io.h"
+#include "misc.h"
+#include "mvcode.h"
+
+#include "mc.h"
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+typedef struct huff_node 
+{
+   int		     code_index;	/* leaf if index >= 0 */
+   struct huff_node *left;		/* follow if '0' bit read */
+   struct huff_node *right;		/* follow if '1' bit read */
+   int		     index_set [34];
+} huff_node_t;
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+decode_mc_tree (frame_type_e frame_type, unsigned max_state,
+		wfa_t *wfa, bitfile_t *input);
+static void
+decode_mc_coords (unsigned max_state, wfa_t *wfa, bitfile_t *input);
+static int
+get_mv (int f_code, huff_node_t *hn, bitfile_t *input);
+static huff_node_t *
+create_huff_tree (void);
+static void
+create_huff_node (huff_node_t *hn, int bits_processed);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+read_mc (frame_type_e frame_type, wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read motion compensation information of the 'input' stream.
+ *  Depending on 'frame_type' different decoding methods are used.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->mv_tree' is filled with the decoded values.
+ */
+{
+   unsigned max_state = wfa->wfainfo->color
+			? wfa->tree [wfa->tree [wfa->root_state][0]][0]
+			: wfa->states;
+
+   decode_mc_tree (frame_type, max_state, wfa, input);
+   decode_mc_coords (max_state, wfa, input);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+decode_mc_tree (frame_type_e frame_type, unsigned max_state,
+		wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read tree of motion compensation decisions of the 'input' stream.
+ *  Depending on 'frame_type' different decoding methods are used.
+ *  'max_state' is the last state with motion compensation infos.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->mv_tree' is filled with decoded values.
+ */
+{
+   unsigned  state;			/* current state */
+   unsigned *queue;			/* states in breadth first order */
+   unsigned  last;			/* last node
+					   (update for each new node) */
+
+   /*
+    *  Traverse tree in breadth first order (starting at level
+    *  'wfa->wfainfo->p_max_level'). Use a queue to store the childs
+    *  of each node ('last' is the next free queue element).  
+    */
+   queue = Calloc (MAXSTATES, sizeof (unsigned));
+   for (last = 0, state = wfa->basis_states; state < max_state; state++)
+      if (wfa->level_of_state [state] - 1 == (int) wfa->wfainfo->p_max_level)
+	 queue [last++] = state;	/* init level 'p_max_level' */
+
+   if (frame_type == P_FRAME)
+   {
+      unsigned label;			/* current label */
+      unsigned current;			/* current node to process */
+      
+      for (current = 0; current < last; current++)
+	 for (label = 0; label < MAXLABELS; label++)
+	 {
+	    state = queue[current];
+	    if (wfa->x [state][label]	/* process visible states only */
+		+  width_of_level (wfa->level_of_state [state] - 1)
+		<= wfa->wfainfo->width
+		&&
+		wfa->y [state][label]
+		+  height_of_level (wfa->level_of_state [state] - 1)
+		<= wfa->wfainfo->height)
+	    {
+	       wfa->mv_tree [state][label].type
+		  = get_bit (input) ? NONE : FORWARD;
+	    }
+	    else
+	       wfa->mv_tree [state][label].type = NONE;
+	    if (wfa->mv_tree [state][label].type == NONE &&
+		!isrange (wfa->tree [state][label]) &&
+		wfa->level_of_state [state] - 1 >=
+		(int) wfa->wfainfo->p_min_level) 
+	       queue [last++] = wfa->tree [state][label]; /* append child  */
+	 }
+   }
+   else
+   {
+      unsigned label;			/* current label */
+      unsigned current;			/* current node to process */
+      
+      for (current = 0; current < last; current++)
+	 for (label = 0; label < MAXLABELS; label++)
+	 {
+	    state = queue[current];
+	    if (wfa->x [state][label]	/* process visible states only */
+		+ width_of_level (wfa->level_of_state [state] - 1)
+		> wfa->wfainfo->width
+		||
+		wfa->y [state][label]
+		+ height_of_level (wfa->level_of_state [state] - 1)
+		> wfa->wfainfo->height)
+	       wfa->mv_tree[state][label].type = NONE;
+	    else if (get_bit (input))	/* 1   */
+	       wfa->mv_tree[state][label].type = NONE;
+	    else if (get_bit (input))	/* 01  */
+	       wfa->mv_tree[state][label].type = INTERPOLATED;
+	    else if (get_bit (input))	/* 001 */ 
+	       wfa->mv_tree[state][label].type = BACKWARD;
+	    else			/* 000 */ 
+	       wfa->mv_tree[state][label].type = FORWARD;
+	    if (wfa->mv_tree[state][label].type == NONE &&
+		!isrange (wfa->tree[state][label]) &&
+		wfa->level_of_state[state] - 1
+		>= (int) wfa->wfainfo->p_min_level) 
+	       queue[last++] = wfa->tree[state][label]; /* append child  */
+	 }
+   }
+   
+   INPUT_BYTE_ALIGN (input);
+   Free (queue);
+}
+
+static void
+decode_mc_coords (unsigned max_state, wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read motion vector coordinates of the 'input' stream. They are stored
+ *  with the static Huffman code of the MPEG and H.263 standards.
+ *  'max_state' is the last state with motion compensation infos.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->mv_tree' is filled with decoded values.
+ */
+{
+   unsigned	       label;		/* current label */
+   unsigned	       state;		/* current state */
+   mv_t		      *mv;		/* current motion vector */
+   static huff_node_t *huff_mv_root = NULL; /* root of huffman tree */
+ 
+   if (huff_mv_root == NULL)
+      huff_mv_root = create_huff_tree ();
+   
+   for (state = wfa->basis_states; state < max_state; state++)
+      for (label = 0; label < MAXLABELS; label++)
+      {
+	 mv = &wfa->mv_tree[state][label];
+	 switch (mv->type)
+	 {
+	    case NONE:
+	       break;
+	    case FORWARD:
+	       mv->fx = get_mv (1, huff_mv_root, input);
+	       mv->fy = get_mv (1, huff_mv_root, input);
+	       break;	    
+	    case BACKWARD:	    
+	       mv->bx = get_mv (1, huff_mv_root, input);
+	       mv->by = get_mv (1, huff_mv_root, input);
+	       break;	    
+	    case INTERPOLATED:   
+	       mv->fx = get_mv (1, huff_mv_root, input);
+	       mv->fy = get_mv (1, huff_mv_root, input);
+	       mv->bx = get_mv (1, huff_mv_root, input);
+	       mv->by = get_mv (1, huff_mv_root, input);
+	       break;
+	 }
+      }
+
+   INPUT_BYTE_ALIGN (input);
+}
+ 
+static int
+get_mv (int f_code, huff_node_t *hn, bitfile_t *input)
+/* 
+ *  Decode next motion vector component in bitstream 
+ *  by traversing the huffman tree.
+ */
+{
+   int vlc_code, vlc_code_magnitude, residual, diffvec;
+
+   while (hn->code_index < 0)
+   {
+      if (hn->code_index == -2)
+	 error ("wrong huffman code !");
+      if (get_bit (input))
+	 hn = hn->right;
+      else
+	 hn = hn->left;
+   }
+   vlc_code = hn->code_index - 16;
+   if (vlc_code == 0 || f_code == 1) 
+      return vlc_code;
+
+   vlc_code_magnitude = abs (vlc_code) - 1;
+   if (f_code <= 1)
+      residual = 0;
+   else
+      residual = get_bits (input, f_code - 1);
+   diffvec = (vlc_code_magnitude << (f_code - 1)) + residual + 1;
+   
+   return vlc_code > 0 ? diffvec : - diffvec;
+}
+
+static huff_node_t *
+create_huff_tree (void)
+/*
+ *  Construct huffman tree from code table
+ */
+{
+   unsigned	i;
+   huff_node_t *huff_root = Calloc (1, sizeof (huff_node_t));
+   
+   /*
+    *  The nodes' index set contains indices of all codewords that are
+    *  still decodable by traversing further down from the node.
+    *  (The root node has the full index set.)
+    */
+
+   for (i = 0; i < 33; i++)
+      huff_root->index_set [i] = i;
+   huff_root->index_set [i] = -1;	/* end marker */
+
+   create_huff_node (huff_root, 0);
+
+   return huff_root;
+}
+
+static void
+create_huff_node (huff_node_t *hn, int bits_processed)
+/*
+ *  Create one node in the huffman tree
+ */
+{
+   int lind = 0;			/* next index of left huff_node */
+   int rind = 0;			/* next index of right huff_node */
+   int code_len, i, ind;
+
+   hn->code_index = -1;
+   if (hn->index_set [0] < 0)		/* empty index set ? */
+   {
+      hn->code_index = -2;		/* error */
+      return;
+   }
+   hn->left  = Calloc (1, sizeof (huff_node_t));
+   hn->right = Calloc (1, sizeof (huff_node_t));
+
+   for (i = 0; (ind = hn->index_set[i]) >= 0; i++)
+   {
+      code_len = mv_code_table[ind][1];
+      if (code_len == bits_processed)	/* generate leaf */
+      {
+	 hn->code_index = ind;
+	 Free (hn->left); 
+	 Free (hn->right);
+	 return;
+      }
+      if (mv_code_table[ind][0] & (1 << (code_len - 1 - bits_processed)))
+	 hn->right->index_set[rind++] = ind;
+      else
+	 hn->left->index_set[lind++] = ind;
+   }
+   hn->right->index_set[rind] = -1;	/* set end markers */
+   hn->left->index_set[lind]  = -1;
+   create_huff_node (hn->left, bits_processed + 1);
+   create_huff_node (hn->right, bits_processed + 1);
+}
diff --git a/converter/other/fiasco/input/mc.h b/converter/other/fiasco/input/mc.h
new file mode 100644
index 00000000..1e14d287
--- /dev/null
+++ b/converter/other/fiasco/input/mc.h
@@ -0,0 +1,28 @@
+/*
+ *  mc.h
+ *
+ *  written by: Michael Unger
+ *		Ullrich Hafner
+ 
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MC_H
+#define _MC_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+void
+read_mc (frame_type_e frame_type, wfa_t *wfa, bitfile_t *input);
+
+#endif /* not _MC_H */
+
diff --git a/converter/other/fiasco/input/nd.c b/converter/other/fiasco/input/nd.c
new file mode 100644
index 00000000..1a68bfbf
--- /dev/null
+++ b/converter/other/fiasco/input/nd.c
@@ -0,0 +1,237 @@
+/*
+ *  nd.c:		Input of prediction tree	
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "bit-io.h"
+#include "arith.h"
+#include "misc.h"
+#include "list.h"
+#include "wfalib.h"
+
+#include "nd.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+decode_nd_coefficients (unsigned total, wfa_t *wfa, bitfile_t *input);
+static unsigned
+decode_nd_tree (wfa_t *wfa, bitfile_t *input);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+read_nd (wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read transitions of the nondetermistic 'wfa' part from 'input' stream.
+ *  ND is used only at levels {'wfa->p_min_level', ... , 'wfa->p_max_level'}.
+ *
+ *  Side effects:
+ *	'wfa->into' and 'wfa->weights' are filled with the decoded values
+ */
+{
+   unsigned total = decode_nd_tree (wfa, input);
+   
+   if (total > 0)
+      decode_nd_coefficients (total, wfa, input);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static unsigned
+decode_nd_tree (wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read 'wfa' prediction tree of given 'input' stream.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->into' is filled with the decoded values
+ */
+{
+   lqueue_t *queue;			/* queue of states */
+   int       next, state;		/* state and its current child */
+   unsigned  total = 0;			/* total number of predicted states */
+   u_word_t  sum0, sum1;		/* Probability model */
+   u_word_t  code;			/* The present input code value */
+   u_word_t  low;			/* Start of the current code range */
+   u_word_t  high;			/* End of the current code range */
+
+   /*
+    *  Initialize arithmetic decoder
+    */
+   code = get_bits (input, 16);
+   low  = 0;
+   high = 0xffff;
+   sum0 = 1;
+   sum1 = 11;
+
+   queue = alloc_queue (sizeof (int));
+   state = wfa->root_state;
+   queue_append (queue, &state);
+
+   /*
+    *  Traverse the WFA tree in breadth first order (using a queue).
+    */
+   while (queue_remove (queue, &next))
+   {
+      unsigned label;
+
+      if (wfa->level_of_state [next] > wfa->wfainfo->p_max_level + 1) 
+      {
+	 /*
+	  *  Nondetermismn is not allowed at levels larger than
+	  *  'wfa->wfainfo->p_max_level'.
+	  */
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (ischild (state = wfa->tree [next][label]))
+	       queue_append (queue, &state); /* continue with childs */
+      }
+      else if (wfa->level_of_state [next] > wfa->wfainfo->p_min_level)
+      {
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (ischild (state = wfa->tree [next][label]))
+	    {
+	       unsigned count;		/* Current interval count */
+	       unsigned range;		/* Current interval range */
+	       
+	       count = (((code - low) + 1) * sum1 - 1) / ((high - low) + 1);
+	       if (count < sum0)
+	       {
+		  /*
+		   *  Decode a '0' symbol
+		   *  First, the range is expanded to account for the
+		   *  symbol removal.
+		   */
+		  range = (high - low) + 1;
+		  high = low + (u_word_t) ((range * sum0) / sum1 - 1 );
+		  RESCALE_INPUT_INTERVAL;
+		  /*
+		   *  Update the frequency counts
+		   */
+		  sum0++;
+		  sum1++;
+		  if (sum1 > 50) /* scale the symbol frequencies */
+		  {
+		     sum0 >>= 1;
+		     sum1 >>= 1;
+		     if (!sum0)
+			sum0 = 1;
+		     if (sum0 >= sum1)
+			sum1 = sum0 + 1;
+		  }
+		  if (wfa->level_of_state [state] > wfa->wfainfo->p_min_level)
+		     queue_append (queue, &state);
+	       }
+	       else
+	       {
+		  /*
+		   *  Decode a '1' symbol
+		   *  First, the range is expanded to account for the
+		   *  symbol removal.
+		   */
+		  range = (high - low) + 1;
+		  high = low + (u_word_t) ((range * sum1) / sum1 - 1);
+		  low  = low + (u_word_t) ((range * sum0) / sum1);
+		  RESCALE_INPUT_INTERVAL;
+		  /*
+		   *  Update the frequency counts
+		   */
+		  sum1++;
+		  if (sum1 > 50) /* scale the symbol frequencies */
+		  {
+		     sum0 >>= 1;
+		     sum1 >>= 1;
+		     if (!sum0)
+			sum0 = 1;
+		     if (sum0 >= sum1)
+			sum1 = sum0 + 1;
+		  }
+		  append_edge (next, 0, -1, label, wfa);
+		  total++;
+	       }
+	    }
+      }
+   }
+   free_queue (queue);
+
+   INPUT_BYTE_ALIGN (input);
+
+   return total;
+}
+
+static void
+decode_nd_coefficients (unsigned total, wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read #'total' weights of nondeterministic part of 'wfa'  
+ *  of given 'input' stream.
+ *  'frame' gives the current frame number.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->weights' is filled with the decoded values.
+ */
+{
+   unsigned *coefficients;		/* array of factors to encode */
+   unsigned *ptr;			/* pointer to current factor */
+   
+   /*
+    *  Decode array of coefficients stored with arithmetic coding
+    */
+   {
+      const int	scaling  = 50;		/* scaling factor of prob. model */
+      unsigned  c_symbols = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1);
+      
+      ptr = coefficients = decode_array (input, NULL, &c_symbols, 1,
+					 total, scaling);
+   }
+   
+   /*
+    *  Fill 'wfa->weights' with decoded coefficients
+    */
+   {
+      unsigned state, label;
+      
+      for (state = wfa->basis_states; state < wfa->states; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (ischild (wfa->tree [state][label])
+		&& isedge (wfa->into [state][label][0]))
+	    {
+	       wfa->weight [state][label][0] = btor (*ptr++,
+						     wfa->wfainfo->dc_rpf);
+	       wfa->int_weight [state][label][0]
+		  = wfa->weight [state][label][0] * 512 + 0.5;
+	    }
+   }
+   Free (coefficients);
+}
diff --git a/converter/other/fiasco/input/nd.h b/converter/other/fiasco/input/nd.h
new file mode 100644
index 00000000..2c2fff4b
--- /dev/null
+++ b/converter/other/fiasco/input/nd.h
@@ -0,0 +1,28 @@
+/*
+ *  nd.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _ND_H
+#define _ND_H
+
+#include "wfa.h"
+#include "rpf.h"
+#include "bit-io.h"
+
+void
+read_nd (wfa_t *wfa, bitfile_t *input);
+
+#endif /* not _ND_H */
+
diff --git a/converter/other/fiasco/input/read.c b/converter/other/fiasco/input/read.c
new file mode 100644
index 00000000..26bae7e4
--- /dev/null
+++ b/converter/other/fiasco/input/read.c
@@ -0,0 +1,499 @@
+/*
+ *  read.c:		Input of WFA files
+ *
+ *  Written by:		Ullrich Hafner
+ *  
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/18 15:44:58 $
+ *  $Author: hafner $
+ *  $Revision: 5.4 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include <string.h>
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "misc.h"
+#include "rpf.h"
+#include "bit-io.h"
+#include "wfalib.h"
+
+#include "tree.h"
+#include "matrices.h"
+#include "weights.h"
+#include "nd.h"
+#include "mc.h"
+#include "basis.h"
+#include "read.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+read_tiling (tiling_t *tiling, unsigned image_width, unsigned image_height,
+	     unsigned image_level, bitfile_t *input);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+bitfile_t *
+open_wfa (const char *filename, wfa_info_t *wi)
+/*
+ *  Open WFA file 'filename' and read header information.
+ *
+ *  Return value:
+ *	Pointer to input stream (fileposition: first WFA frame)
+ *
+ *  Side effects:
+ *	The values of the header of 'filename' are copied to 'wfainfo'. 
+ *
+ */
+{
+   bitfile_t *input;			/* pointer to WFA bitfile */
+   
+   assert (filename && wi);
+   
+   wi->wfa_name = strdup (filename);
+
+   /*
+    *  Check whether 'filename' is a regular WFA file
+    */
+   {
+      unsigned 	n;
+      const char     *str;
+      
+      if (!(input = open_bitfile (filename, "FIASCO_DATA", READ_ACCESS)))
+          file_error (filename);
+   
+      for (str = FIASCO_MAGIC, n = strlen (FIASCO_MAGIC); n; n--)
+          if (get_bits (input, 8) != (unsigned) *str++)
+              error ("Input file %s is not a valid FIASCO file!", filename);
+      get_bits (input, 8);		/* fetch newline */
+   }
+   
+   /*
+    *  Read WFA header information
+    */
+   {
+      char	      basis_name [MAXSTRLEN]; /* temp. buffer */
+      const unsigned  rice_k = 8; 	/* parameter of Rice Code */
+      char     	     *str    = basis_name;
+      
+      while ((*str++ = get_bits (input, 8)) != 0
+	     && str < basis_name + MAXSTRLEN)
+	 ;
+      if (str == basis_name + MAXSTRLEN)
+	 error ("Input file %s is not a valid FIASCO file!", filename);
+      
+      {
+	 wi->release = read_rice_code (rice_k, input);
+
+	 if (wi->release > FIASCO_BINFILE_RELEASE)
+	    error ("Can't decode FIASCO files of file format release `%d'."
+		   "\nCurrent file format release is `%d'.", wi->release,
+		   FIASCO_BINFILE_RELEASE);
+      }
+
+      if (wi->release > 1)
+      {
+	 header_type_e type;
+	 
+	 while ((type = read_rice_code (rice_k, input)) != HEADER_END)
+	 {
+	    char     buffer [MAXSTRLEN];
+	    unsigned n = 0;
+	    
+	    switch (type)
+	    {
+	       case HEADER_TITLE:
+		  while ((buffer [n++] = get_bits (input, 8)))
+		     ;
+		  wi->title = strdup (buffer);
+		  break;
+	       case HEADER_COMMENT:
+		  while ((buffer [n++] = get_bits (input, 8)))
+		     ;
+		  wi->comment = strdup (buffer);
+		  break;
+	       default:			/* should not happen */
+		  break;
+	    }
+	 }
+      }
+
+      wi->basis_name = strdup (basis_name);
+      wi->max_states = read_rice_code (rice_k, input);
+      wi->color      = get_bit (input) ? YES : NO;
+      wi->width      = read_rice_code (rice_k, input);
+      wi->height     = read_rice_code (rice_k, input);
+
+      /*
+       *  Compute bintree level
+       */
+      {
+	 unsigned lx = log2 (wi->width - 1) + 1;
+	 unsigned ly = log2 (wi->height - 1) + 1;
+      
+	 wi->level = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0);
+      }
+      wi->chroma_max_states = wi->color ? read_rice_code (rice_k, input) : -1;
+      wi->p_min_level       = read_rice_code (rice_k, input);
+      wi->p_max_level       = read_rice_code (rice_k, input);
+      wi->frames            = read_rice_code (rice_k, input);
+      wi->smoothing	    = read_rice_code (rice_k, input);
+
+      /*
+       *  Read RPF models from disk
+       */
+      {
+	 unsigned 	    mantissa;
+	 fiasco_rpf_range_e range;
+
+	 mantissa = get_bits (input, 3) + 2;
+	 range    = get_bits (input, 2);
+	 wi->rpf  = alloc_rpf (mantissa, range);
+	 
+	 if (get_bit (input))		/* different DC model */
+	 {
+	    mantissa   = get_bits (input, 3) + 2;
+	    range      = get_bits (input, 2);
+	    wi->dc_rpf = alloc_rpf (mantissa, range);
+	 }
+	 else				/* use same model for DC coefficents */
+	    wi->dc_rpf = alloc_rpf (wi->rpf->mantissa_bits,
+				    wi->rpf->range_e);
+
+	 if (get_bit (input))		/* different delta model */
+	 {
+	    mantissa  = get_bits (input, 3) + 2;
+	    range     = get_bits (input, 2);
+	    wi->d_rpf = alloc_rpf (mantissa, range);
+	 }
+	 else
+	    wi->d_rpf = alloc_rpf (wi->rpf->mantissa_bits,
+				   wi->rpf->range_e);
+	 
+	 if (get_bit (input))		/* different DC delta model */
+	 {
+	    mantissa  	 = get_bits (input, 3) + 2;
+	    range     	 = get_bits (input, 2);
+	    wi->d_dc_rpf = alloc_rpf (mantissa, range);
+	 }
+	 else
+	    wi->d_dc_rpf = alloc_rpf (wi->dc_rpf->mantissa_bits,
+				      wi->dc_rpf->range_e);
+      }
+
+      if (wi->frames > 1)		/* motion compensation stuff */
+      {
+	 wi->fps           = read_rice_code (rice_k, input);
+	 wi->search_range  = read_rice_code (rice_k, input);
+	 wi->half_pixel    = get_bit (input) ? YES : NO;
+	 wi->B_as_past_ref = get_bit (input) ? YES : NO;
+      }
+   }
+   
+   INPUT_BYTE_ALIGN (input);
+
+   return input;
+}
+
+void
+read_basis (const char *filename, wfa_t *wfa)
+/*
+ *  Read WFA initial basis 'filename' and fill 'wfa' struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	wfa->into, wfa->weights, wfa->final_distribution, wfa->basis_states
+ *	wfa->domain_type wfa->wfainfo->basis_name, are filled with the
+ *	values of the WFA basis.
+ */
+{
+   FILE	*input;				/* ASCII WFA initial basis file */
+
+   assert (filename && wfa);
+
+   if (!wfa->wfainfo->basis_name ||
+       !streq (wfa->wfainfo->basis_name, filename))
+   {
+      if (wfa->wfainfo->basis_name)
+	 Free (wfa->wfainfo->basis_name);
+      wfa->wfainfo->basis_name = strdup (filename);
+   }
+   
+   if (get_linked_basis (filename, wfa))
+      return;				/* basis is linked with excecutable */
+   
+   /*
+    *  Check whether 'wfa_name' is a regular ASCII WFA initial basis file
+    */
+   {
+      char magic [MAXSTRLEN];		/* WFA magic number */
+
+      if (!(input = open_file (filename, "FIASCO_DATA", READ_ACCESS)))
+	 file_error(filename);
+      
+      if (fscanf (input, MAXSTRLEN_SCANF, magic) != 1)
+	 error ("Format error: ASCII FIASCO initial basis file %s", filename);
+      else if (strneq (FIASCO_BASIS_MAGIC, magic))
+	 error ("Input file %s is not an ASCII FIASCO initial basis!",
+		filename);
+   }
+   
+   /*
+    *  WFA ASCII format:
+    *
+    *  Note: State 0 is assumed to be the constant function f(x, y) = 128.
+    *        Don't define any transitions of state 0 in an initial basis. 
+    *
+    *  Header:
+    *   type		|description
+    *	----------------+-----------
+    *   string		|MAGIC Number "Wfa"
+    *	int		|Number of basis states 'N'
+    *	bool_t-array[N]	|use vector in linear combinations,
+    *			|0: don't use vector (auxilliary state)
+    *			|1: use vector in linear combinations
+    *	float-array[N]	|final distribution of every state
+    *
+    *  Transitions:
+    *
+    *      <state 1>			current state
+    *      <label> <into> <weight>	transition 1 of current state
+    *      <label> <into> <weight>	transition 2 of current state
+    *      ...
+    *      <-1>				last transition marker
+    *      <state 2>
+    *      ...
+    *      <-1>				last transition marker
+    *      <state N>
+    *      ...
+    *
+    *      <-1>				last transition marker
+    *      <-1>				last state marker
+    */
+   {
+      unsigned state;
+
+      if (fscanf (input ,"%u", &wfa->basis_states) != 1)
+	 error ("Format error: ASCII FIASCO initial basis file %s", filename);
+
+      /*
+       *  State 0 is assumed to be the constant function f(x, y) = 128.
+       */
+      wfa->domain_type [0]        = USE_DOMAIN_MASK; 
+      wfa->final_distribution [0] = 128;
+      wfa->states 		  = wfa->basis_states;
+      wfa->basis_states++;
+
+      append_edge (0, 0, 1.0, 0, wfa);
+      append_edge (0, 0, 1.0, 1, wfa);
+   
+      for (state = 1; state < wfa->basis_states; state++)
+	 wfa->domain_type [state]
+	    = read_int (input) ? USE_DOMAIN_MASK : AUXILIARY_MASK;
+
+      for (state = 1; state < wfa->basis_states; state++)
+	 wfa->final_distribution[state] = read_real (input);
+
+      /*
+       *  Read transitions
+       */
+      for (state = 1; state < wfa->basis_states; state++)
+      {
+	 unsigned domain;
+	 int      label;
+	 real_t   weight;
+
+	 if (read_int (input) != (int) state)
+	    error ("Format error: ASCII FIASCO initial basis file %s",
+		   filename);
+
+	 while((label = read_int (input)) != -1)
+	 {
+	    domain = read_int (input);
+	    weight = read_real (input);
+	    append_edge (state, domain, weight, label, wfa);
+	 }
+      }
+   }
+   
+   fclose (input);
+}
+
+unsigned
+read_next_wfa (wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read next WFA frame of the WFA stream 'input'.
+ *  WFA header information has to be already present in the 'wfainfo' struct.
+ *  (i.e. open_wfa must be called first!)
+ *  
+ *  No return value.
+ *
+ *  Side effects:
+ *	wfa->into, wfa->weights, wfa->final_distribution, wfa->states
+ *	wfa->x, wfa->y, wfa->level_of_state, wfa->domain_type
+ *      mt->type, mt->number are filled with the values of the WFA file.
+ */
+{
+   tiling_t tiling;			/* tiling information */
+   unsigned frame_number;		/* current frame number */
+   
+   assert (wfa && input);
+   
+   /*
+    *  Frame header information
+    */
+   {
+      const unsigned rice_k = 8;	/* parameter of Rice Code */
+
+      wfa->states     = read_rice_code (rice_k, input);
+      wfa->frame_type = read_rice_code (rice_k, input);
+      frame_number    = read_rice_code (rice_k, input);
+   }
+
+   if (wfa->wfainfo->release > 1)	/* no alignment in version 1 */
+   {
+      INPUT_BYTE_ALIGN (input);
+   }
+   
+   /*
+    *  Read image tiling info 
+    */
+   if (get_bit (input))			/* tiling performed ? */
+      read_tiling (&tiling, wfa->wfainfo->width, wfa->wfainfo->height,
+		   wfa->wfainfo->level, input);
+   else
+      tiling.exponent = 0;
+   
+   INPUT_BYTE_ALIGN (input);
+
+   read_tree (wfa, &tiling, input);
+
+   /*
+    *  Compute domain pool.
+    *  Large images have not been used due to image tiling.
+    */
+   {
+      unsigned state;
+   
+      for (state = wfa->basis_states; state < wfa->states; state++)
+	 if ((!wfa->wfainfo->color
+	      || (int) state <= wfa->tree [wfa->tree [wfa->root_state][0]][0])
+	     &&
+	     (!tiling.exponent ||
+	      wfa->level_of_state [state] <= (wfa->wfainfo->level
+					      - tiling.exponent))
+	     && ((wfa->x [state][0]
+		 + width_of_level (wfa->level_of_state [state]))
+		 <= wfa->wfainfo->width)
+	     && ((wfa->y [state][0]
+		 + height_of_level (wfa->level_of_state [state]))
+		 <= wfa->wfainfo->height))
+	    wfa->domain_type [state] = USE_DOMAIN_MASK;
+	 else
+	    wfa->domain_type [state] = 0;
+   }
+   
+   if (tiling.exponent)
+      Free (tiling.vorder);
+
+   if (get_bit (input))			/* nondeterministic prediction used */
+      read_nd (wfa, input);
+
+   if (wfa->frame_type != I_FRAME)	/* motion compensation used */
+      read_mc (wfa->frame_type, wfa, input);
+
+   locate_delta_images (wfa);
+   
+   /*
+    *  Read linear combinations (coefficients and indices)
+    */
+   {
+      unsigned edges = read_matrices (wfa, input); 
+
+      if (edges)
+	 read_weights (edges, wfa, input);
+   }
+
+   /*
+    *  Compute final distribution of all states
+    */
+   {
+      unsigned state;
+   
+      for (state = wfa->basis_states; state <= wfa->states; state++)
+	 wfa->final_distribution[state]
+	    = compute_final_distribution (state, wfa);
+   }
+
+   return frame_number;
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+read_tiling (tiling_t *tiling, unsigned image_width, unsigned image_height,
+	     unsigned image_level, bitfile_t *input)
+/*
+ *  Read image tiling information from the given file 'input'
+ *  and store parameters in struct 'tiling'.
+ *  
+ *  No return value.
+ */
+{
+   const unsigned rice_k = 8;		/* parameter of Rice Code */
+   
+   tiling->exponent = read_rice_code (rice_k, input);
+   
+   if (get_bit (input))			/* variance order */
+   {
+      unsigned tile;			/* current image tile */
+      unsigned x0, y0;			/* NW corner of image tile */
+      unsigned width, height;		/* size of image tile */
+
+      tiling->vorder = Calloc (1 << tiling->exponent, sizeof (int));
+      for (tile = 0; tile <  1U << tiling->exponent; tile++)
+      {
+	 locate_subimage (image_level, image_level - tiling->exponent, tile,
+			  &x0, &y0, &width, &height);
+	 if (x0 < image_width && y0 < image_height) 
+	    tiling->vorder [tile] = get_bits (input, tiling->exponent);
+	 else
+	    tiling->vorder [tile] = -1;
+      }
+   }
+   else					/* spiral order */
+   {
+      tiling->vorder = Calloc (1 << tiling->exponent, sizeof (int));
+      compute_spiral (tiling->vorder, image_width, image_height,
+		      tiling->exponent, get_bit (input) ? YES : NO);
+   }
+}
diff --git a/converter/other/fiasco/input/read.h b/converter/other/fiasco/input/read.h
new file mode 100644
index 00000000..d0d0ee13
--- /dev/null
+++ b/converter/other/fiasco/input/read.h
@@ -0,0 +1,31 @@
+/*
+ *  read.h
+ *
+ *  Written by:		Ullrich Hafner
+ *  
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _READ_H
+#define _READ_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+bitfile_t *
+open_wfa (const char *filename, wfa_info_t *wfainfo);
+void
+read_basis (const char *filename, wfa_t *wfa);
+unsigned
+read_next_wfa (wfa_t *wfa, bitfile_t *input);
+
+#endif /* not _READ_H */
+
diff --git a/converter/other/fiasco/input/tree.c b/converter/other/fiasco/input/tree.c
new file mode 100644
index 00000000..e3e7117e
--- /dev/null
+++ b/converter/other/fiasco/input/tree.c
@@ -0,0 +1,303 @@
+/*
+ *  tree.c:		Input of bintree partitioning
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "bit-io.h"
+#include "arith.h"
+#include "misc.h"
+#include "wfalib.h"
+#include "tiling.h"
+
+#include "tree.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static unsigned
+restore_depth_first_order (unsigned src_state, unsigned level, unsigned x,
+			   unsigned y, unsigned *dst_state,
+			   word_t (*bfo_tree)[MAXLABELS],
+			   wfa_t *wfa, tiling_t *tiling);
+static void 
+decode_tree (bitfile_t *input, byte_t *data, unsigned n_data, unsigned scaling,
+	     u_word_t sum0, u_word_t sum1);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+read_tree (wfa_t *wfa, tiling_t *tiling, bitfile_t *input)
+/*
+ *  Read bintree partitioning of WFA from the 'input' stream.
+ *  'tiling' provides the information about image tiling, if applied.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->tree', 'wfa->x', 'wfa->y', 'wfa->level_of_state'
+ *      are filled with decoded values.
+ */
+{
+   byte_t *bitstring;			/* the encoded data */
+   word_t (*bfo_tree)[MAXLABELS];	/* node numbers in BFO */
+      
+   /*
+    *  Read WFA tree stored in breadth first order
+    */
+   {
+      unsigned total = (wfa->states - wfa->basis_states) * MAXLABELS;
+      unsigned scale = total / 20;
+
+      bitstring = Calloc (total, sizeof (byte_t));
+      decode_tree (input, bitstring, total, scale, 1, 11);
+   }
+   
+   /*
+    *  Generate tree using a breadth first traversal
+    */
+   {
+      unsigned 	next;			/* next free node number of the tree */
+      unsigned 	state;
+      unsigned 	label;
+      byte_t   *buffer = bitstring;	/* pointer to decoded data */
+      
+      bfo_tree = Calloc (wfa->states * MAXLABELS, sizeof (word_t));
+      for (state = 0, next = 1; state < next; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    bfo_tree [state][label] = *buffer++ ? next++ : RANGE;
+   }
+
+   /*
+    *  Traverse tree and restore depth first order
+    */
+   {
+      unsigned dst_state = wfa->basis_states;
+
+      wfa->root_state
+	 = restore_depth_first_order (0, (wfa->wfainfo->level
+					  + (wfa->wfainfo->color ? 2 : 0)),
+				      0, 0, &dst_state, bfo_tree, wfa, tiling);
+   }
+
+   Free (bitstring);
+   Free (bfo_tree);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static unsigned
+restore_depth_first_order (unsigned src_state, unsigned level, unsigned x,
+			   unsigned y, unsigned *dst_state,
+			   word_t (*bfo_tree)[MAXLABELS],
+			   wfa_t *wfa, tiling_t *tiling)
+/*
+ *  Map state 'src_state' (breadth first order) 
+ *  to state '*dst_state' (depth first order)
+ *  Add a tree edge 'state' --> 'child' with label and weight 1.0
+ *  if required.
+ *  'x', 'y' give the coordinates of the current state in the 'color' image
+ *  of size 'image_level'. 'tiling' defines the image partitioning. 
+ *  
+ *  Return value:
+ *	new node number in depth first order
+ *
+ *  Side effects:
+ *	'wfa->tree', 'wfa->x', 'wfa->y', 'wfa->level_of_state'
+ *      are filled with decoded values.
+ */
+{
+   unsigned newx [MAXLABELS];		/* x coordinate of childs */
+   unsigned newy [MAXLABELS];		/* y coordinate of childs */
+   unsigned x0, y0;			/* NW corner of image tile */
+   unsigned width, height;		/* size of image tile */
+
+   /*
+    *  If tiling is performed then replace current coordinates
+    */
+   if (tiling->exponent && level == wfa->wfainfo->level - tiling->exponent)
+   {
+      unsigned tile;
+      
+      for (tile = 0; tile < 1U << tiling->exponent; tile++)
+      {
+	 locate_subimage (wfa->wfainfo->level, level, tile,
+			  &x0, &y0, &width, &height);
+	 if (x0 == x && y0 == y) /* matched ! */
+	 {
+	    locate_subimage (wfa->wfainfo->level, level, tiling->vorder[tile],
+			     &x, &y, &width, &height);
+	    break;
+	 }
+      }
+   }
+   /*
+    *  Coordinates of childs 0 and 1
+    */
+   if (wfa->wfainfo->color && level == wfa->wfainfo->level + 1)
+      newx[0] = newy[0] = newx[1] = newy[1] = 0;
+   else
+   {
+      newx[0] = x;
+      newy[0] = y;
+      newx[1] = level & 1 ? x : x + width_of_level (level - 1);
+      newy[1] = level & 1 ? y + height_of_level (level - 1) : y;
+   }
+   
+   /*
+    *  Remap node numbers
+    */
+   {
+      int      child [MAXLABELS];	/* childs of current node (state) */
+      int      domain;			/* current domain */
+      unsigned label;
+
+      for (label = 0; label < MAXLABELS; label++)
+	 if (!isrange (domain = bfo_tree [src_state][label]))
+	    child [label] = restore_depth_first_order (domain, level - 1,
+						       newx [label],
+						       newy [label], dst_state,
+						       bfo_tree, wfa, tiling);
+	 else
+	    child [label] = RANGE;
+
+      for (label = 0; label < MAXLABELS; label++)
+      {
+	 wfa->tree [*dst_state][label] = child [label];
+	 wfa->x [*dst_state][label]    = newx [label];
+	 wfa->y [*dst_state][label]    = newy [label];
+      }
+      wfa->level_of_state [*dst_state] = level;
+   }
+   
+   return (*dst_state)++;
+}	
+
+/****************************************************************************
+
+                 Binary adaptive arithmetic compression
+ 
+****************************************************************************/
+
+static void 
+decode_tree (bitfile_t *input, byte_t *data, unsigned n_data, unsigned scaling,
+	     u_word_t sum0, u_word_t sum1)
+/*
+ *  Decode bintree partitioning using adaptive binary arithmetic decoding.
+ *  'input'	input stream,
+ *  'data'	buffer for decoded szmbols,
+ *  'n_data'	number of symbols to decode,
+ *  'scaling'	rescale probability models if range > 'scaling'
+ *  'sum0'	initial totals of symbol '0'
+ *  'sum1'	initial totals of symbol '1'
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'data []' is filled with the decoded bitstring
+ */
+{
+   u_word_t code;			/* The present input code value */
+   u_word_t low;			/* Start of the current code range */
+   u_word_t high;			/* End of the current code range */
+   unsigned n;				/* Data counter */
+
+   assert (data);
+
+   code = get_bits (input, 16);
+   low  = 0;
+   high = 0xffff;
+
+   for (n = n_data; n; n--) 
+   {
+      unsigned count;			/* Current interval count */
+      unsigned range;			/* Current interval range */
+      
+      count = (((code - low) + 1) * sum1 - 1) / ((high - low) + 1);
+      if (count < sum0)
+      {
+	 /*
+	  *  Decode a '0' symbol
+	  *  First, the range is expanded to account for the symbol removal.
+	  */
+	 range = (high - low) + 1;
+	 high = low + (u_word_t) ((range * sum0) / sum1 - 1 );
+
+	 RESCALE_INPUT_INTERVAL;
+
+	 *data++ = 0;
+	 /*
+	  *  Update the frequency counts
+	  */
+	 sum0++;
+	 sum1++;
+	 if (sum1 > scaling) /* scale the symbol frequencies */
+	 {
+	    sum0 >>= 1;
+	    sum1 >>= 1;
+	    if (!sum0)
+	       sum0 = 1;
+	    if (sum0 >= sum1)
+	       sum1 = sum0 + 1;
+	 }
+
+      }
+      else
+      {
+	 /*
+	  *  Decode a '1' symbol
+	  *  First, the range is expanded to account for the symbol removal.
+	  */
+	 range = (high - low) + 1;
+	 high = low + (u_word_t) ((range * sum1) / sum1 - 1);
+	 low  = low + (u_word_t) ((range * sum0) / sum1);
+
+	 RESCALE_INPUT_INTERVAL;
+
+	 *data++ = 1;
+	 /*
+	  *  Update the frequency counts
+	  */
+	 sum1++;
+	 if (sum1 > scaling) /* scale the symbol frequencies */
+	 {
+	    sum0 >>= 1;
+	    sum1 >>= 1;
+	    if (!sum0)
+	       sum0 = 1;
+	    if (sum0 >= sum1)
+	       sum1 = sum0 + 1;
+	 }
+      }
+   }
+   INPUT_BYTE_ALIGN (input);
+}
+
+
diff --git a/converter/other/fiasco/input/tree.h b/converter/other/fiasco/input/tree.h
new file mode 100644
index 00000000..e4b5f2d8
--- /dev/null
+++ b/converter/other/fiasco/input/tree.h
@@ -0,0 +1,28 @@
+/*
+ *  tree.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _TREE_H
+#define _TREE_H
+
+#include "wfa.h"
+#include "bit-io.h"
+#include "tiling.h"
+
+void
+read_tree (wfa_t *wfa, tiling_t *tiling, bitfile_t *input);
+
+#endif /* not _TREE_H */
+
diff --git a/converter/other/fiasco/input/weights.c b/converter/other/fiasco/input/weights.c
new file mode 100644
index 00000000..55339980
--- /dev/null
+++ b/converter/other/fiasco/input/weights.c
@@ -0,0 +1,200 @@
+/*
+ *  weights.c:		Input of weights
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "bit-io.h"
+#include "arith.h"
+#include "rpf.h"
+#include "misc.h"
+
+#include "weights.h"
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+read_weights (unsigned total, wfa_t *wfa, bitfile_t *input)
+/*
+ *  Read #'total' weights from input stream 'input' and
+ *  update transitions of the WFA states with corresponding weights.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'wfa->weights' are filled with the decoded values
+ */
+{
+   unsigned	    state;
+   unsigned	    label;
+   unsigned	    edge;		/* current edge */
+   unsigned	   *weights_array;	/* array of weights to encode */
+   unsigned	   *level_array;	/* array of corresponding levels */
+   unsigned	    offset1, offset2;	/* prob. model offsets. */
+   unsigned	    offset3, offset4;	/* prob. model offsets. */
+   bool_t	    delta_approx = NO; 	/* true if delta has been used */
+   
+   /*
+    *  Check whether delta approximation has been used
+    */
+   for (state = wfa->basis_states; state < wfa->states; state++)
+      if (wfa->delta_state [state])
+      {
+	 delta_approx = YES;
+	 break;
+      }
+  
+   /*
+    *  Generate array of corresponding levels (context of probability model)
+    */
+   {
+      int 	min_level, max_level; 	/* min and max range level */
+      int 	d_min_level, d_max_level; /* min and max range level (delta) */
+      unsigned *lptr;			/* pointer to current corresp. level */
+      int	domain;			/* current domain */
+      bool_t	dc, d_dc;		/* indicates whether DC is used */
+
+      /*
+       *  Compute minimum and maximum level of delta and normal approximations
+       */
+      min_level = d_min_level = MAXLEVEL;
+      max_level = d_max_level = 0;
+      dc 	= d_dc	   = NO;
+   
+      for (state = wfa->basis_states; state < wfa->states; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (isrange (wfa->tree [state][label]))
+	    {
+	       if (delta_approx && wfa->delta_state [state])
+	       {
+		  d_min_level = min (d_min_level,
+				     wfa->level_of_state [state] - 1);
+		  d_max_level = max (d_max_level,
+				     wfa->level_of_state [state] - 1);
+		  if (wfa->into [state][label][0] == 0)
+		     d_dc = YES;
+	       }
+	       else
+	       {
+		  min_level = min (min_level, wfa->level_of_state [state] - 1);
+		  max_level = max (max_level, wfa->level_of_state [state] - 1);
+		  if (wfa->into [state][label][0] == 0)
+		     dc = YES;
+	       }
+	    }
+      if (min_level > max_level)		/* no lc found */
+	 max_level = min_level - 1;
+      if (d_min_level > d_max_level)
+	 d_max_level = d_min_level - 1;
+
+      offset1 = dc ? 1 : 0;
+      offset2 = offset1 + (d_dc ? 1 : 0);
+      offset3 = offset2 + (max_level - min_level + 1);
+      offset4 = offset3 + (d_max_level - d_min_level + 1);
+
+      lptr = level_array = Calloc (total, sizeof (int));
+      for (state = wfa->basis_states; state < wfa->states; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (isrange (wfa->tree[state][label]))
+	       for (edge = 0; isedge (domain = wfa->into[state][label][edge]);
+		    edge++)
+	       {
+		  if ((unsigned) (lptr - level_array) >= total)
+		     error ("Can't read more than %d weights.", total);
+		  if (domain)
+		  {
+		     if (delta_approx && wfa->delta_state [state])
+			*lptr++ = offset3 + wfa->level_of_state [state]
+				  - 1 - d_min_level;
+		     else
+			*lptr++ = offset2 + wfa->level_of_state [state]
+				  - 1 - min_level;
+		  }
+		  else
+		     *lptr++ = delta_approx && wfa->delta_state [state]
+			       ? offset1 : 0;
+	       }
+   }
+
+   /*
+    *  Decode the list of weights with an arithmetic decoder
+    */
+   {
+      unsigned	      i;
+      unsigned	     *c_symbols = Calloc (offset4, sizeof (unsigned));
+      const unsigned  scale 	= 500; 	/* scaling of probability model */
+
+      c_symbols [0] = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1);
+      if (offset1 != offset2)
+	 c_symbols [offset1] = 1 << (wfa->wfainfo->d_dc_rpf->mantissa_bits
+				     + 1);
+      for (i = offset2; i < offset3; i++)
+	 c_symbols [i] = 1 << (wfa->wfainfo->rpf->mantissa_bits + 1);
+      for (; i < offset4; i++)
+	 c_symbols [i] = 1 << (wfa->wfainfo->d_rpf->mantissa_bits + 1);
+      
+      weights_array = decode_array (input, level_array, c_symbols,
+				    offset4, total, scale);
+      Free (c_symbols);
+   }
+   Free (level_array);
+
+   /*
+    *  Update transitions with decoded weights
+    */
+   {
+      unsigned *wptr = weights_array;	/* pointer to current weight */
+      int	domain;			/* current domain */
+
+      for (state = wfa->basis_states; state < wfa->states; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (isrange (wfa->tree[state][label]))
+	       for (edge = 0; isedge (domain = wfa->into[state][label][edge]);
+		    edge++)
+	       {
+		  if (domain)		/* not DC component */
+		  {
+		     if (delta_approx && wfa->delta_state [state])
+			wfa->weight [state][label][edge]
+			   = btor (*wptr++, wfa->wfainfo->d_rpf);
+		     else
+			wfa->weight [state][label][edge]
+			   = btor (*wptr++, wfa->wfainfo->rpf);
+		  }
+		  else
+		  {
+		     if (delta_approx && wfa->delta_state [state])
+			wfa->weight [state][label][edge]
+			   = btor (*wptr++, wfa->wfainfo->d_dc_rpf);
+		     else
+			wfa->weight [state][label][edge]
+			   = btor (*wptr++, wfa->wfainfo->dc_rpf);
+		  }
+		  wfa->int_weight [state][label][edge]
+		     = wfa->weight [state][label][edge] * 512 + 0.5;
+	       }
+   }
+   
+   Free (weights_array);
+}
+ 
diff --git a/converter/other/fiasco/input/weights.h b/converter/other/fiasco/input/weights.h
new file mode 100644
index 00000000..1e2285a9
--- /dev/null
+++ b/converter/other/fiasco/input/weights.h
@@ -0,0 +1,27 @@
+/*
+ *  weights.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:13 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _WEIGHTS_H
+#define _WEIGHTS_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+void
+read_weights (unsigned total, wfa_t *wfa, bitfile_t *input);
+
+#endif /* not _WEIGHTS_H */
+
diff --git a/converter/other/fiasco/lib/Makefile b/converter/other/fiasco/lib/Makefile
new file mode 100644
index 00000000..99d7c1d7
--- /dev/null
+++ b/converter/other/fiasco/lib/Makefile
@@ -0,0 +1,33 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/../../../..
+  BUILDDIR = $(SRCDIR)
+endif
+FIASCOSUBDIR = converter/other/fiasco
+SUBDIR = $(FIASCOSUBDIR)/lib
+VPATH=.:$(SRCDIR)/$(SUBDIR)
+
+include $(BUILDDIR)/Makefile.config
+
+OBJECTS = \
+  arith.o \
+  bit-io.o \
+  dither.o \
+  error.o \
+  image.o \
+  list.o \
+  misc.o \
+  rpf.o \
+  mvcode.o \
+
+MERGE_OBJECTS = $(OBJECTS)
+
+INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR)
+
+all: libfiasco_lib.a
+
+include $(SRCDIR)/Makefile.common
+
+libfiasco_lib.a: $(OBJECTS)
+	$(AR) -rc $@ $(OBJECTS)
+	$(RANLIB) $@
+
diff --git a/converter/other/fiasco/lib/arith.c b/converter/other/fiasco/lib/arith.c
new file mode 100644
index 00000000..e3745bf7
--- /dev/null
+++ b/converter/other/fiasco/lib/arith.c
@@ -0,0 +1,708 @@
+/*
+ *  arith.c:		Adaptive arithmetic coding and decoding
+ *
+ *  Written by:		Ullrich Hafner
+ *  
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "bit-io.h"
+#include "misc.h"
+#include "arith.h"
+
+/******************************************************************************
+
+				public code
+  
+******************************************************************************/
+
+arith_t *
+alloc_encoder (bitfile_t *output)
+/*
+ *  Arithmetic coder constructor:
+ *  Initialize the arithmetic coder.
+ *  
+ *  Return value:
+ *	A pointer to the new coder structure
+ */
+{
+   arith_t *arith = Calloc (1, sizeof (arith_t));
+
+   assert (output);
+   
+   arith->low       = LOW;
+   arith->high      = HIGH;
+   arith->underflow = 0;
+   arith->file 	    = output;
+
+   return arith;
+}
+
+void
+free_encoder (arith_t *arith)
+/*
+ *  Arithmetic encoder destructor.
+ *  Flush the arithmetic coder. Append all remaining bits to the
+ *  output stream. Append zero bits to get the output file byte aligned.
+ *  
+ *  No return value.
+ */
+{
+   u_word_t   low;			/* start of the current code range  */
+   u_word_t   high;			/* end of the current code range    */
+   u_word_t   underflow;		/* number of underflow bits pending */
+   bitfile_t *output;
+   
+   assert (arith);
+
+   low       = arith->low;
+   high      = arith->high;
+   underflow = arith->underflow;
+   output    = arith->file;
+   
+   low = high;
+
+   RESCALE_OUTPUT_INTERVAL;
+
+   OUTPUT_BYTE_ALIGN (output);
+
+   Free (arith);
+}
+
+real_t
+encode_symbol (unsigned symbol, arith_t *arith, model_t *model)
+/*
+ *  Encode the given 'symbol' using the given probability 'model'.
+ *  The current state of the arithmetic coder is given by 'arith'.
+ *  Output bits are appended to the stream 'output'.
+ *
+ *  The model is updated after encoding the symbol (if neccessary the
+ *  symbol counts are rescaled).
+ *  
+ *  Return value:
+ *	information content of the encoded symbol.
+ *
+ *  Side effects:
+ *	'model' is updated (probability distribution)
+ *	'arith' is updated (coder state)
+ */
+{
+   u_word_t   low_count;		/* lower bound of 'symbol' interval */
+   u_word_t   high_count;		/* upper bound of 'symbol' interval */
+   u_word_t   scale;			/* range of all 'm' symbol intervals */
+   unsigned   range;			/* range of current interval */
+   unsigned   index;			/* index of probability model */
+   u_word_t   low;			/* start of the current code range  */
+   u_word_t   high;			/* end of the current code range    */
+   u_word_t   underflow;		/* number of underflow bits pending */
+   bitfile_t *output;			/* output file */
+   
+   assert (model && arith);
+
+   /*
+    * Get interval values
+    */
+   low       = arith->low;
+   high      = arith->high;
+   underflow = arith->underflow;
+   output    = arith->file;
+
+   assert (high > low);
+   
+   if (model->order > 0)		/* order-'n' model*/
+   {
+      unsigned power;			/* multiplicator */
+      unsigned i;
+
+      /*
+       *  Compute index of the probability model to use.
+       *  See init_model() for more details.
+       */
+      power = 1;			/* multiplicator */
+      index = 0;			/* address of prob. model */
+	 
+      for (i = 0; i < model->order; i++) /* genarate a M-nary number */
+      {
+	 index += model->context [i] * power;	
+	 power *= model->symbols;
+      }
+
+      index *= model->symbols + 1;	/* we need space for M + 1 elements */
+
+      for (i = 0; i < model->order - 1; i++)
+	 model->context [i] = model->context [i + 1];
+      model->context [i] = symbol;
+   }
+   else
+      index = 0;
+
+   scale      = model->totals [index + model->symbols];
+   low_count  = model->totals [index + symbol];
+   high_count = model->totals [index + symbol + 1];
+
+   /*
+    *  Compute the new interval depending on the input 'symbol'.
+    */
+   range = (high - low) + 1;
+   high  = low + (u_word_t) ((range * high_count) / scale - 1);
+   low   = low + (u_word_t) ((range * low_count) / scale);
+   
+   RESCALE_OUTPUT_INTERVAL;
+   
+   if (model->scale > 0)		/* adaptive model */
+   {
+      unsigned i;
+
+      /*
+       *  Update probability model
+       */
+      for (i = symbol + 1; i <= model->symbols; i++)
+	 model->totals [index + i]++;
+      if (model->totals [index + model->symbols] > model->scale) /* scaling */
+      {
+	 for (i = 1; i <= model->symbols; i++)
+	 {
+	    model->totals [index + i] >>= 1;
+	    if (model->totals [index + i] <= model->totals [index + i - 1])
+	       model->totals [index + i] = model->totals [index + i - 1] + 1;
+	 }
+      }
+   }
+
+   /*
+    *  Store interval values
+    */
+   arith->low  	    = low;
+   arith->high 	    = high;
+   arith->underflow = underflow;
+   
+   return - log2 ((high_count - low_count) / (real_t) scale);
+}
+
+void
+encode_array (bitfile_t *output, const unsigned *data, const unsigned *context,
+	      const unsigned *c_symbols, unsigned n_context, unsigned n_data,
+	      unsigned scaling)
+/*
+ *  Arithmetic coding of #'n_data' symbols given in the array 'data'.
+ *  If 'n_context' > 1 then a number (context [n]) is assigned to every
+ *  data element n, specifying which context (i.e. number of symbols given by
+ *  c_symbols [context [n]] and adaptive probability model) must be used.
+ *  Rescale probability models if range > 'scaling'.
+ *
+ *  No return value.
+ */
+{
+   u_word_t **totals;			/* probability model */
+
+   if (!n_context)
+      n_context = 1;			/* always use one context */
+
+   assert (output && c_symbols && data);
+   assert (n_context == 1 || context);
+   
+   /*
+    *  Allocate probability models, start with uniform distribution
+    */
+   totals = Calloc (n_context, sizeof (u_word_t *));
+   {
+      unsigned c;
+      
+      for (c = 0; c < n_context; c++)
+      {
+	 unsigned i;
+      
+	 totals [c]    = Calloc (c_symbols [c] + 1, sizeof (u_word_t));
+	 totals [c][0] = 0;
+      
+	 for (i = 0; i < c_symbols [c]; i++)
+	    totals [c][i + 1] = totals [c][i] + 1;
+      }
+   }
+
+   /*
+    *  Encode array elements
+    */
+   {
+      u_word_t low  	 = 0;		/* Start of the current code range */
+      u_word_t high 	 = 0xffff;	/* End of the current code range */
+      u_word_t underflow = 0;		/* Number of underflow bits pending */
+      unsigned n;
+      
+      for (n = 0; n < n_data; n++)
+      {
+	 u_word_t low_count;		/* lower bound of 'symbol' interval */
+	 u_word_t high_count;		/* upper bound of 'symbol' interval */
+	 u_word_t scale;		/* range of all 'm' symbol intervals */
+	 unsigned range;		/* current range */
+	 int	  d;			/* current data symbol */
+	 int	  c;			/* context of current data symbol */
+
+	 d = data [n];
+	 c = n_context > 1 ? context [n] : 0; 
+      
+	 scale	    = totals [c][c_symbols [c]];
+	 low_count  = totals [c][d];
+	 high_count = totals [c][d + 1];
+
+	 /*
+	  * Rescale high and low for the new symbol.
+	  */
+	 range = (high - low) + 1;
+	 high  = low + (u_word_t) ((range * high_count) / scale - 1);
+	 low   = low + (u_word_t) ((range * low_count) / scale);
+	 RESCALE_OUTPUT_INTERVAL;
+      
+	 /*
+	  *  Update probability models
+	  */
+	 {
+	    unsigned i;
+
+	    for (i = d + 1; i < c_symbols [c] + 1; i++)
+	       totals [c][i]++;
+	 
+	    if (totals [c][c_symbols [c]] > scaling) /* scaling */
+	       for (i = 1; i < c_symbols [c] + 1; i++)
+	       {
+		  totals [c][i] >>= 1;
+		  if (totals [c][i] <= totals [c][i - 1])
+		     totals [c][i] = totals [c][i - 1] + 1;
+	       }
+	 }
+      }
+      /*
+       *  Flush arithmetic encoder
+       */
+      low = high;
+      RESCALE_OUTPUT_INTERVAL;
+      OUTPUT_BYTE_ALIGN (output);
+   }
+   
+   /*
+    *  Cleanup ...
+    */
+   {
+      unsigned c;
+      for (c = 0; c < n_context; c++)
+	 Free (totals [c]);
+      Free (totals);
+   }
+}
+
+arith_t *
+alloc_decoder (bitfile_t *input)
+/*
+ *  Arithmetic decoder constructor:
+ *  Initialize the arithmetic decoder with the first
+ *  16 input bits from the stream 'input'.
+ *  
+ *  Return value:
+ *	A pointer to the new decoder structure
+ */
+
+{
+   arith_t *arith = Calloc (1, sizeof (arith_t));
+   
+   assert (input);
+   
+   arith->low  = LOW;
+   arith->high = HIGH;
+   arith->code = get_bits (input, 16);
+   arith->file = input;
+
+   return arith;
+}
+
+void
+free_decoder (arith_t *arith)
+/*
+ *  Arithmetic decoder destructor:
+ *  Flush the arithmetic decoder, i.e., read bits to get the input
+ *  file byte aligned. 
+ *  
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'arith' is discarded.
+ */
+{
+   assert (arith);
+
+   INPUT_BYTE_ALIGN (arith->file);
+
+   Free (arith);
+}
+
+unsigned
+decode_symbol (arith_t *arith, model_t *model)
+/*
+ *  Decode the next symbol - the state of the arithmetic decoder
+ *  is given in 'arith'. Read refinement bits from the stream 'input'
+ *  and use the given probability 'model'. Update the probability model after
+ *  deconding the symbol (if neccessary also rescale the symbol counts).
+ *  
+ *  Return value:
+ *	decoded symbol
+ *
+ *  Side effects:
+ *	'model' is updated (probability distribution)
+ *	'arith' is updated (decoder state)
+ */
+{
+   unsigned   range;			/* range of current interval */
+   unsigned   count;			/* value in the current interval */
+   unsigned   index;			/* index of probability model */
+   unsigned   symbol;			/* decoded symbol */
+   u_word_t   scale;			/* range of all 'm' symbol intervals */
+   u_word_t   low;			/* start of the current code range  */
+   u_word_t   high;			/* end of the current code range    */
+   u_word_t   code;			/* the present input code value */
+   bitfile_t *input;			/* input file */
+
+   assert (arith && model);
+   
+   /*
+    * Get interval values
+    */
+   low   = arith->low;
+   high  = arith->high;
+   code  = arith->code;
+   input = arith->file;
+
+   assert (high > low);
+   
+   if (model->order > 0)		/* order-'n' model */
+   {
+      unsigned power;			/* multiplicator */
+      unsigned i;
+      
+      /*
+       *  Compute index of the probability model to use.
+       *  See init_model() for more details.
+       */
+      power = 1;			/* multiplicator */
+      index = 0;			/* address of prob. model */
+	 
+      for (i = 0; i < model->order; i++) /* genarate a m-nary number */
+      {
+	 index += model->context[i] * power;	
+	 power *= model->symbols;
+      }
+
+      index *= model->symbols + 1;	/* we need space for m + 1 elements */
+   }
+   else
+      index = 0;
+
+   scale = model->totals [index + model->symbols];
+   range = (high - low) + 1;
+   count = ((code - low + 1) * scale - 1) / range;
+
+   for (symbol = model->symbols; count < model->totals [index + symbol];
+	symbol--)
+      ;
+
+   if (model->order > 0)		/* order-'n' model */
+   {
+      unsigned i;
+      
+      for (i = 0; i < model->order - 1; i++)
+	 model->context [i] = model->context [i + 1];
+      model->context [i] = symbol;
+   }
+
+   /*
+    *  Compute interval boundaries
+    */
+   {
+      u_word_t low_count;		/* lower bound of 'symbol' interval */
+      u_word_t high_count;		/* upper bound of 'symbol' interval */
+      
+      low_count  = model->totals [index + symbol];
+      high_count = model->totals [index + symbol + 1];
+      high       = low + (u_word_t) ((range * high_count) / scale - 1 );
+      low        = low + (u_word_t) ((range * low_count) / scale );
+   }
+   
+   RESCALE_INPUT_INTERVAL;
+   
+   if (model->scale > 0)		/* adaptive model */
+   {
+      unsigned i;
+
+      /*
+       *  Update probability model
+       */
+      for (i = symbol + 1; i <= model->symbols; i++)
+	 model->totals [index + i]++;
+      if (model->totals [index + model->symbols] > model->scale) /* scaling */
+      {
+	 for (i = 1; i <= model->symbols; i++)
+	 {
+	    model->totals [index + i] >>= 1;
+	    if (model->totals [index + i] <= model->totals [index + i - 1])
+	       model->totals [index + i] = model->totals [index + i - 1] + 1;
+	 }
+      }
+   }
+   
+   /*
+    *  Store interval values
+    */
+   arith->low  = low;
+   arith->high = high;
+   arith->code = code;
+
+   return symbol;
+}
+
+unsigned *
+decode_array (bitfile_t *input, const unsigned *context,
+	      const unsigned *c_symbols, unsigned n_context,
+	      unsigned n_data, unsigned scaling)
+/*
+ *  Arithmetic decoding of #'n_data' symbols.
+ *  If 'n_context' > 1 then a number (context [n]) is assigned to every
+ *  data element n, specifying which context (i.e. number of symbols given by
+ *  c_symbols [context [n]] and adaptive probability model) must be used.
+ *  Rescale probability models if range > 'scaling'.
+ *
+ *  Return value:
+ *	pointer to array containing the decoded symbols
+ */
+{
+   unsigned  *data;			/* array to store decoded symbols */
+   u_word_t **totals;			/* probability model */
+   
+   if (n_context < 1)
+      n_context = 1;			/* always use one context */
+   assert (input && c_symbols);
+   assert (n_context == 1 || context);
+
+   data = Calloc (n_data, sizeof (unsigned));
+   
+   /*
+    *  Allocate probability models, start with uniform distribution
+    */
+   totals = Calloc (n_context, sizeof (u_word_t *));
+   {
+      unsigned c;
+      
+      for (c = 0; c < n_context; c++)
+      {
+	 unsigned i;
+      
+	 totals [c]    = Calloc (c_symbols [c] + 1, sizeof (u_word_t));
+	 totals [c][0] = 0;
+      
+	 for (i = 0; i < c_symbols [c]; i++)
+	    totals [c][i + 1] = totals [c][i] + 1;
+      }
+   }
+
+   /*
+    *  Fill array 'data' with decoded values
+    */
+   {
+      u_word_t code = get_bits (input, 16); /* The present input code value */
+      u_word_t low  = 0;		/* Start of the current code range */
+      u_word_t high = 0xffff;		/* End of the current code range */
+      unsigned n;
+      
+      for (n = 0; n < n_data; n++) 
+      {
+	 u_word_t scale;		/* range of all 'm' symbol intervals */
+	 u_word_t low_count;		/* lower bound of 'symbol' interval */
+	 u_word_t high_count;		/* upper bound of 'symbol' interval */
+	 unsigned count;		/* value in the current interval */
+	 unsigned range;		/* current interval range */
+	 unsigned d;			/* current data symbol */
+	 unsigned c;			/* context of current data symbol */
+
+	 c = n_context > 1 ? context [n] : 0; 
+
+	 assert (high > low);
+	 scale = totals [c][c_symbols [c]];
+	 range = (high - low) + 1;
+	 count = (((code - low) + 1 ) * scale - 1) / range;
+      
+	 for (d = c_symbols [c]; count < totals [c][d]; d--) /* next symbol */
+	    ;
+	 low_count  = totals [c][d];
+	 high_count = totals [c][d + 1];
+
+	 high = low + (u_word_t) ((range * high_count) / scale - 1 );
+	 low  = low + (u_word_t) ((range * low_count) / scale );
+	 RESCALE_INPUT_INTERVAL;
+
+	 /*
+	  *  Updata probability models
+	  */
+	 {
+	    unsigned i;
+
+	    for (i = d + 1; i < c_symbols [c] + 1; i++)
+	       totals [c][i]++;
+	 
+	    if (totals [c][c_symbols [c]] > scaling) /* scaling */
+	       for (i = 1; i < c_symbols [c] + 1; i++)
+	       {
+		  totals [c][i] >>= 1;
+		  if (totals [c][i] <= totals [c][i - 1])
+		     totals [c][i] = totals [c][i - 1] + 1;
+	       }
+	 }
+	 data [n] = d;
+      }
+      INPUT_BYTE_ALIGN (input);
+   }
+
+   /*
+    *  Cleanup ...
+    */
+   {
+      unsigned c;
+      
+      for (c = 0; c < n_context; c++)
+	 Free (totals [c]);
+      Free (totals);
+   }
+   
+   return data;
+}
+
+model_t *
+alloc_model (unsigned m, unsigned scale, unsigned n, unsigned *totals)
+/*
+ *  Model constructor:
+ *  allocate and initialize an order-'n' probability model.
+ *  The size of the source alphabet is 'm'. Rescale the symbol counts after
+ *  'scale' symbols are encoded/decoded. The initial probability of every
+ *  symbol is 1/m.
+ *  If 'scale' = 0 then use static modeling (p = 1/n).
+ *  If 'totals' is not NULL then use this array of 'm' values to set
+ *  the initial counts.
+ *
+ *  Return value:
+ *	a pointer to the new probability model structure.
+ *  
+ *  Note: We recommend a small size of the alphabet because no escape codes
+ *  are used to encode/decode previously unseen symbols.
+ *  
+ */
+{
+   model_t  *model;			/* new probability model */
+   unsigned  num;			/* number of contexts to allocate */
+   bool_t    cont;			/* continue flag */
+   bool_t    dec;			/* next order flag */
+   unsigned  i;
+
+   /*
+    *  Allocate memory for the structure
+    */
+   model          = Calloc (1, sizeof (model_t));
+   model->symbols = m;
+   model->scale   = scale;
+   model->order   = n;
+   model->context = n > 0 ? Calloc (n, sizeof (unsigned)) : NULL;
+   /*
+    *  Allocate memory for the probabilty model.
+    *  Each of the m^n different contexts requires its own probability model.
+    */
+   for (num = 1, i = 0; i < model->order; i++)
+      num *= model->symbols;
+
+   model->totals = Calloc (num * (model->symbols + 1), sizeof (unsigned));
+
+   for (i = 0; i < model->order; i++)
+      model->context[i] = 0;		/* start with context 0,0, .. ,0 */
+   cont = YES;
+   while (cont)				/* repeat while context != M ... M */
+   {
+      int	power;			/* multiplicator */
+      int	index;			/* index of probability model */
+      /*
+       *  There are m^n different contexts:
+       *  Let "context_1 context_2 ... context_n symbol" be the current input
+       *  stream then the index of the probability model is given by:
+       *  index = context_1 * M^0 + context_2 * M^1 + ... + context_n * M^(n-1)
+       */
+      power = 1;			/* multiplicator */
+      index = 0;			/* address of prob. model */
+	 
+      for (i = 0; i < model->order; i++)	/* genarate a m-nary number */
+      {
+	 index += model->context[i] * power;	
+	 power *= model->symbols;
+      }
+
+      index *= model->symbols + 1;	/* size of each model is m + 1 */
+
+      model->totals [index + 0] = 0;	/* always zero */
+	 
+      for (i = 1; i <= model->symbols; i++) /* prob of each symbol is 1/m or
+					       as given in totals */
+	 model->totals[index + i] = model->totals [index + i - 1]
+				    + (totals ? totals [i - 1] : 1);
+
+      if (model->order == 0)		/* order-0 model */
+	 cont = NO;
+      else				/* try next context */
+	 for (i = model->order - 1, dec = YES; dec; i--)
+	 {
+	    dec = NO;
+	    model->context[i]++;
+	    if (model->context[i] >= model->symbols) 
+	    {
+	       /* change previous context */
+	       model->context[i] = 0;
+	       if (i > 0)		/* there's still a context remaining */
+		  dec = YES;
+	       else
+		  cont = NO;		/* all context models initilized */
+	    }
+	 }
+   }
+   for (i = 0; i < model->order; i++)
+      model->context[i] = 0;		/* start with context 0,0, .. ,0 */
+
+   return model;
+}
+
+void
+free_model (model_t *model)
+/*
+ *  Model destructor:
+ *  Free memory allocated by the arithmetic 'model'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	struct 'model' is discarded
+ */
+{
+   if (model != NULL)
+   {
+      if (model->context != NULL)
+	 Free (model->context);
+      Free (model->totals);
+      Free (model);
+   }
+   else
+      warning ("Can't free model <NULL>.");
+}
diff --git a/converter/other/fiasco/lib/arith.h b/converter/other/fiasco/lib/arith.h
new file mode 100644
index 00000000..744eb9d7
--- /dev/null
+++ b/converter/other/fiasco/lib/arith.h
@@ -0,0 +1,122 @@
+/*
+ *  arith.h
+ *
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _ARITH_H
+#define _ARITH_H
+
+#include "types.h"
+#include "bit-io.h"
+
+typedef struct model
+{
+   unsigned  symbols;			/* number of symbols in the alphabet */
+   unsigned  scale;			/* if totals > scale rescale totals */
+   unsigned  order;			/* order of the probability model */
+   unsigned *context;			/* context of the model */
+   unsigned *totals;			/* the totals */
+} model_t;
+
+typedef struct arith
+{
+   u_word_t   low;			/* start of the current code range */
+   u_word_t   high;			/* end of the current code range */
+   u_word_t   underflow;		/* number of underflow bits pending */
+   u_word_t   code;			/* the present input code value */
+   bitfile_t *file;			/* I/O stream */
+} arith_t;
+
+enum interval {LOW = 0x0000, FIRST_QUARTER = 0x4000, HALF = 0x8000,
+	       THIRD_QUARTER = 0xc000, HIGH = 0xffff};
+
+arith_t *
+alloc_encoder (bitfile_t *file);
+void
+free_encoder (arith_t *arith);
+real_t
+encode_symbol (unsigned symbol, arith_t *arith, model_t *model);
+void
+encode_array (bitfile_t *output, const unsigned *data, const unsigned *context,
+	      const unsigned *c_symbols, unsigned n_context, unsigned n_data,
+	      unsigned scaling);
+arith_t *
+alloc_decoder (bitfile_t *input);
+void
+free_decoder (arith_t *arith);
+unsigned
+decode_symbol (arith_t *arith, model_t *model);
+unsigned *
+decode_array (bitfile_t *input, const unsigned *context,
+	      const unsigned *c_symbols, unsigned n_context,
+	      unsigned n_data, unsigned scaling);
+model_t *
+alloc_model (unsigned m, unsigned scale, unsigned n, unsigned *totals);
+void
+free_model (model_t *model);
+
+#define RESCALE_INPUT_INTERVAL  for (;;)                                      \
+                                   if ((high >= HALF) && (low < HALF) &&      \
+                                      ((low & FIRST_QUARTER) != FIRST_QUARTER \
+				       || (high & FIRST_QUARTER) != 0))       \
+                                   {                                          \
+                                      break;                                  \
+                                   }                                          \
+                                   else if ((high < HALF) || (low >= HALF))   \
+                                   {                                          \
+                                      low  <<= 1;                             \
+                                      high <<= 1;                             \
+                                      high  |= 1;                             \
+                                      code <<= 1;                             \
+                                      code  += get_bit (input);               \
+                                   }                                          \
+                                   else                                       \
+                                   {                                          \
+                                      code  ^= FIRST_QUARTER;                 \
+                                      low   &= FIRST_QUARTER - 1;             \
+                                      low  <<= 1;                             \
+                                      high <<= 1;                             \
+                                      high  |= HALF + 1;                      \
+                                      code <<= 1;                             \
+                                      code  += get_bit (input);               \
+                                   }                                          
+        								   
+#define RESCALE_OUTPUT_INTERVAL  for (;;)                                     \
+                                 {                                            \
+                                    if (high < HALF)                          \
+                                    {                                         \
+                                       put_bit (output, 0);                   \
+                                       for (; underflow; underflow--)         \
+                                          put_bit (output, 1);                \
+                                    }                                         \
+                                    else if (low >= HALF)                     \
+                                    {                                         \
+                                       put_bit (output, 1);                   \
+                                       for (; underflow; underflow--)         \
+                                          put_bit (output, 0);                \
+                                    }                                         \
+                                    else if (high < THIRD_QUARTER &&          \
+                                             low >= FIRST_QUARTER)            \
+                                    {                                         \
+                                       underflow++;                           \
+                                       high |= FIRST_QUARTER;                 \
+                                       low  &= FIRST_QUARTER - 1;             \
+                                    }                                         \
+                                    else                                      \
+                                       break;                                 \
+                                    high <<= 1;                               \
+                                    high  |= 1;                               \
+                                    low  <<= 1;                               \
+                                 }                                             
+					 
+#endif /* not _ARITH_H */
+
diff --git a/converter/other/fiasco/lib/bit-io.c b/converter/other/fiasco/lib/bit-io.c
new file mode 100644
index 00000000..364a1c05
--- /dev/null
+++ b/converter/other/fiasco/lib/bit-io.c
@@ -0,0 +1,327 @@
+/*
+ *  bit-io.c:       Buffered and bit oriented file I/O 
+ *
+ *  Written by:     Ullrich Hafner
+ *  
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+ 
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+
+#include <string.h>
+#if STDC_HEADERS
+#   include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include "macros.h"
+#include "types.h"
+#include "error.h"
+
+#include "misc.h"
+#include "bit-io.h"
+
+/*****************************************************************************
+
+                 local constants
+  
+*****************************************************************************/
+
+static const unsigned BUFFER_SIZE = 16350;
+
+static const unsigned mask[] = {0x0001, 0x0002, 0x0004, 0x0008,
+                                0x0010, 0x0020, 0x0040, 0x0080,
+                                0x0100, 0x0200, 0x0400, 0x0800,
+                                0x1000, 0x2000, 0x4000, 0x8000};
+
+/*****************************************************************************
+
+                public code
+  
+*****************************************************************************/
+
+FILE *
+open_file (const char *filename, const char *env_var, openmode_e mode)
+/*
+ *  Try to open file 'filename' with mode 'mode' (READ_ACCESS, WRITE_ACCESS).
+ *  Scan the current directory first and then cycle through the
+ *  path given in the environment variable 'env_var', if set.
+ * 
+ *  Return value:
+ *  Pointer to open file on success, else NULL.
+ */
+{
+    char       *path;        /* current path */
+    FILE       *fp;      /* file pointer of I/O stream */
+    char       *ext_filename = NULL; /* full path of file */
+    char       *env_path     = NULL; /* path given by 'env_var' */
+    char const * const PATH_SEP     = " ;:,"; /* path separation characters */
+    char const * const DEFAULT_PATH = "."; /* default for output files */
+    const char * const read_mode  = "rb";
+    const char * const write_mode = "wb";
+
+
+    assert (mode == READ_ACCESS || mode == WRITE_ACCESS);
+
+    /*
+     *  First check for stdin or stdout
+     */
+    if (filename == NULL || streq (filename, "-"))
+    {
+        if (mode == READ_ACCESS)
+            return stdin;
+        else 
+            return stdout;
+    }
+   
+    /*
+     *  Try to open 'readonly' file in the current directory
+     */
+    if (mode == READ_ACCESS && (fp = fopen (filename, read_mode)))
+        return fp; 
+
+    if (mode == WRITE_ACCESS && strchr (filename, '/')) /* contains path */
+        return fopen (filename, write_mode);
+   
+    /*
+     *  Get value of environment variable 'env_var', if set
+     *  else use DEFAULT_PATH ("./")
+     */
+    if (env_var != NULL)
+        env_path = getenv (env_var);
+    if (env_path == NULL) 
+        env_path = strdup (DEFAULT_PATH);
+    else
+        env_path = strdup (env_path);
+   
+    /*
+     *  Try to open file in the directory given by the environment
+     *  variable env_var - individual path components are separated by PATH_SEP 
+     */
+    path = strtok (env_path, PATH_SEP);
+    do 
+    {
+        if (ext_filename) 
+            Free (ext_filename);
+        ext_filename =  Calloc (strlen (path) + strlen (filename) + 2,
+                                sizeof (char));
+        strcpy (ext_filename, path); 
+        if (*(ext_filename + strlen (ext_filename) - 1) != '/')
+            strcat (ext_filename, "/");
+        strcat (ext_filename, filename);
+        fp = fopen (ext_filename, mode == READ_ACCESS ? read_mode : write_mode);
+    }
+    while (fp == NULL && (path = strtok (NULL, PATH_SEP)) != NULL);
+
+    Free (env_path);
+   
+    return fp;
+}
+
+bitfile_t *
+open_bitfile (const char *filename, const char *env_var, openmode_e mode)
+/*
+ *  Bitfile constructor:
+ *  Try to open file 'filename' for buffered bit oriented access with mode
+ *  'mode'. Scan the current directory first and then cycle through the path
+ *  given in the environment variable 'env_var', if set.
+ *
+ *  Return value:
+ *  Pointer to open bitfile on success,
+ *      otherwise the program is terminated.
+ */
+{
+    bitfile_t *bitfile = Calloc (1, sizeof (bitfile_t));
+   
+    bitfile->file = open_file (filename, env_var, mode);
+
+    if (bitfile->file == NULL)
+        file_error (filename);
+
+    if (mode == READ_ACCESS)
+    {
+        bitfile->bytepos  = 0;
+        bitfile->bitpos   = 0;
+        bitfile->mode     = mode;
+        bitfile->filename = filename ? strdup (filename) : strdup ("(stdin)");
+    }
+    else if (mode == WRITE_ACCESS)
+    {
+        bitfile->bytepos  = BUFFER_SIZE - 1;
+        bitfile->bitpos   = 8;
+        bitfile->mode     = mode;
+        bitfile->filename = filename ? strdup (filename) : strdup ("(stdout)");
+    }
+    else
+        error ("Unknow file access mode '%d'.", mode);
+   
+    bitfile->bits_processed = 0;
+    bitfile->buffer         = Calloc (BUFFER_SIZE, sizeof (byte_t));
+    bitfile->ptr            = bitfile->buffer;
+
+    return bitfile;
+}
+
+bool_t
+get_bit (bitfile_t *bitfile)
+/*
+ *  Get one bit from the given stream 'bitfile'.
+ *
+ *  Return value:
+ *   1  H bit
+ *   0  L bit
+ *
+ *  Side effects:
+ *  Buffer of 'bitfile' is modified accordingly.
+ */
+{
+    assert (bitfile);
+   
+    if (!bitfile->bitpos--)      /* use next byte ? */
+    {
+        bitfile->ptr++;
+        if (!bitfile->bytepos--)      /* no more bytes left in the buffer? */
+        {
+            /*
+             *  Fill buffer with new data
+             */
+            int bytes = fread (bitfile->buffer, sizeof (byte_t),
+                               BUFFER_SIZE, bitfile->file) - 1;
+            if (bytes < 0)         /* Error or EOF */
+                error ("Can't read next bit from bitfile %s.", bitfile->filename);
+            else
+                bitfile->bytepos = bytes;
+
+            bitfile->ptr = bitfile->buffer;
+        }
+        bitfile->bitpos = 7;
+    }
+
+    bitfile->bits_processed++;
+
+    return *bitfile->ptr & mask [bitfile->bitpos] ? 1 : 0;
+}
+
+unsigned int
+get_bits (bitfile_t *bitfile, unsigned bits)
+/*
+ *  Get #'bits' bits from the given stream 'bitfile'.
+ *
+ *  Return value:
+ *  composed integer value
+ *
+ *  Side effects:
+ *  Buffer of 'bitfile' is modified.
+ */
+{
+    unsigned value = 0;          /* input value */
+   
+    while (bits--)
+        value = (unsigned) (value << 1) | get_bit (bitfile);
+
+    return value;
+}
+
+void
+put_bit (bitfile_t *bitfile, unsigned value)
+/*     
+ *  Put the bit 'value' to the bitfile buffer.
+ *  The buffer is written to the file 'bitfile->file' if the number of
+ *  buffer bytes exceeds 'BUFFER_SIZE'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *  Buffer of 'bitfile' is modified.
+ */
+{
+    assert (bitfile);
+   
+    if (!bitfile->bitpos--)      /* use next byte ? */
+    {
+        bitfile->ptr++;
+        if (!bitfile->bytepos--)      /* no more bytes left ? */
+        {
+            /*
+             *  Write buffer to disk and fill buffer with zeros
+             */
+            if (fwrite (bitfile->buffer, sizeof (byte_t),
+                        BUFFER_SIZE, bitfile->file) != BUFFER_SIZE)
+                error ("Can't write next bit of bitfile %s!", bitfile->filename);
+            memset (bitfile->buffer, 0, BUFFER_SIZE);
+            bitfile->bytepos = BUFFER_SIZE - 1;
+            bitfile->ptr     = bitfile->buffer;
+        }
+        bitfile->bitpos = 7;
+    }
+   
+    if (value)
+        *bitfile->ptr |= mask [bitfile->bitpos];
+
+    bitfile->bits_processed++;
+}
+
+void
+put_bits (bitfile_t *bitfile, unsigned value, unsigned bits)
+/*     
+ *  Put #'bits' bits of integer 'value' to the bitfile buffer 'bitfile'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *  Buffer of 'bitfile' is modified.
+ */
+{
+    while (bits--)
+        put_bit (bitfile, value & mask [bits]);
+}
+
+void
+close_bitfile (bitfile_t *bitfile)
+/*
+ *  Bitfile destructor:
+ *  Close 'bitfile', if 'bitfile->mode' == WRITE_ACCESS write bit buffer
+ *  to disk. 
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *  Structure 'bitfile' is discarded.
+ */
+{
+    assert (bitfile);
+   
+    if (bitfile->mode == WRITE_ACCESS)
+    {
+        unsigned bytes = fwrite (bitfile->buffer, sizeof (byte_t),
+                                 BUFFER_SIZE - bitfile->bytepos, bitfile->file);
+        if (bytes != BUFFER_SIZE - bitfile->bytepos)
+            error ("Can't write remaining %d bytes of bitfile "
+                   "(only %d bytes written)!",
+                   BUFFER_SIZE - bitfile->bytepos, bytes);
+    }
+    fclose (bitfile->file);
+    Free (bitfile->buffer);
+    Free (bitfile->filename);
+    Free (bitfile);
+}
+
+unsigned
+bits_processed (const bitfile_t *bitfile)
+/*
+ *  Return value:
+ *  Number of bits processed up to now
+ */
+{
+    return bitfile->bits_processed;
+}
diff --git a/converter/other/fiasco/lib/bit-io.h b/converter/other/fiasco/lib/bit-io.h
new file mode 100644
index 00000000..d37cc47c
--- /dev/null
+++ b/converter/other/fiasco/lib/bit-io.h
@@ -0,0 +1,58 @@
+/*
+ *  bit-io.h
+ *
+ *  Written by:		Ullrich Hafner
+ *
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _BIT_IO_H
+#define _BIT_IO_H
+
+#include <stdio.h>
+#include "types.h"
+
+#define OUTPUT_BYTE_ALIGN(bfile) while ((bfile)->bitpos) put_bit (bfile, 0);
+#define INPUT_BYTE_ALIGN(bfile)  while ((bfile)->bitpos) get_bit (bfile);
+
+typedef enum {READ_ACCESS, WRITE_ACCESS} openmode_e;
+
+typedef struct bitfile
+{
+   FILE	      *file;			/* associated filepointer */
+   char	      *filename;		/* corresponding filename */
+   byte_t     *buffer;			/* stream buffer */
+   byte_t     *ptr;			/* pointer to current buffer pos */
+   unsigned    bytepos;			/* current I/O byte */
+   unsigned    bitpos;			/* current I/O bit */
+   unsigned    bits_processed;		/* number of bits already processed */
+   openmode_e  mode;			/* access mode */
+} bitfile_t;
+
+FILE *
+open_file (const char *filename, const char *env_var, openmode_e mode);
+bitfile_t *
+open_bitfile (const char *filename, const char *env_var, openmode_e mode);
+void
+put_bit (bitfile_t *bitfile, unsigned value);
+void
+put_bits (bitfile_t *bitfile, unsigned value, unsigned bits);
+bool_t
+get_bit (bitfile_t *bitfile);
+unsigned 
+get_bits (bitfile_t *bitfile, unsigned bits);
+void
+close_bitfile (bitfile_t *bitfile);
+unsigned
+bits_processed (const bitfile_t *bitfile);
+
+#endif /* not _BIT_IO_H */
+
diff --git a/converter/other/fiasco/lib/dither.c b/converter/other/fiasco/lib/dither.c
new file mode 100644
index 00000000..c7f9ebab
--- /dev/null
+++ b/converter/other/fiasco/lib/dither.c
@@ -0,0 +1,1892 @@
+/*
+ *  dither.c:		Various dithering routines 	
+ *
+ *  Adapted by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ * Copyright (c) 1995 Erik Corry
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+ * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+ * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
+ * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/*
+ *  $Date: 2000/11/27 20:22:51 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "fiasco.h"
+#include "image.h"
+#include "misc.h"
+#include "dither.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static int 
+display_16_bit (const struct fiasco_renderer *this, unsigned char *ximage,
+		const fiasco_image_t *fiasco_image);
+static int 
+display_24_bit_bgr (const struct fiasco_renderer *this, unsigned char *ximage,
+		    const fiasco_image_t *fiasco_image);
+static int 
+display_24_bit_rgb (const struct fiasco_renderer *this, unsigned char *ximage,
+		    const fiasco_image_t *fiasco_image);
+static int 
+display_32_bit (const struct fiasco_renderer *this, unsigned char *ximage,
+		const fiasco_image_t *fiasco_image);
+static int
+free_bits_at_bottom (unsigned long a);
+static int
+free_bits_at_top (unsigned long a);
+static int
+number_of_bits_set (unsigned long a);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+fiasco_renderer_t *
+fiasco_renderer_new (unsigned long red_mask, unsigned long green_mask,
+		     unsigned long blue_mask, unsigned bpp,
+		     int double_resolution)
+/*
+ *  FIASCO renderer constructor.
+ *  Allocate memory for the FIASCO renderer structure and
+ *  initialize values.
+ *  `red_mask', `green_mask', and `blue_mask' are the corresponding masks
+ *  of the X11R6 XImage structure. 
+ *  `bpp' gives the depth of the image in bits per pixel (16, 24, or 32).
+ *  If `double_resolution' is not 0 the the image width and height is doubled.
+ *  (fast pixel doubling, no interpolation!)
+ *
+ *  Return value:
+ *	pointer to the new structure or NULL on error
+ */
+{
+   if (bpp != 16 && bpp != 24 && bpp !=32)
+   {
+      set_error (_("Rendering depth of XImage must be 16, 24, or 32 bpp."));
+      return NULL;
+   }
+   else
+   {
+      fiasco_renderer_t  *render    = calloc (1, sizeof (fiasco_renderer_t));
+      renderer_private_t *private   = calloc (1, sizeof (renderer_private_t));
+      bool_t 	       	  twopixels = (bpp == 16 && double_resolution);
+      int 		  crval, cbval, i; /* counter */
+
+      if (!render || !private)
+      {
+	 set_error (_("Out of memory."));
+	 return NULL;
+      }
+      switch (bpp)
+      {
+	 case 16:
+	    render->render = display_16_bit;
+	    break;
+	 case 24:
+	    if (red_mask > green_mask)
+	       render->render = display_24_bit_rgb;
+	    else
+	       render->render = display_24_bit_bgr;
+	    break;
+	 case 32:
+	    render->render = display_32_bit;
+	    break;
+	 default:
+	    break;			/* does not happen */
+      }
+      render->private = private;
+      render->delete  = fiasco_renderer_delete;
+
+      private->double_resolution = double_resolution;
+      private->Cr_r_tab = calloc (256 + 2 * 1024, sizeof (int));
+      private->Cr_g_tab = calloc (256 + 2 * 1024, sizeof (int));
+      private->Cb_g_tab = calloc (256 + 2 * 1024, sizeof (int));
+      private->Cb_b_tab = calloc (256 + 2 * 1024, sizeof (int));
+
+      if (!private->Cr_r_tab || !private->Cr_g_tab
+	  || !private->Cb_b_tab || !private->Cb_g_tab)
+      {
+	 set_error (_("Out of memory."));
+	 return NULL;
+      }
+      
+      for (i = 1024; i < 1024 + 256; i++)
+      {
+	 cbval = crval  = i - 128 - 1024;
+
+	 private->Cr_r_tab [i] =  1.4022 * crval + 0.5;
+	 private->Cr_g_tab [i] = -0.7145 * crval + 0.5;
+	 private->Cb_g_tab [i] = -0.3456 * cbval + 0.5; 
+	 private->Cb_b_tab [i] =  1.7710 * cbval + 0.5;
+      }
+      for (i = 0; i < 1024; i++)
+      {
+	 private->Cr_r_tab [i] = private->Cr_r_tab [1024];
+	 private->Cr_g_tab [i] = private->Cr_g_tab [1024];
+	 private->Cb_g_tab [i] = private->Cb_g_tab [1024]; 
+	 private->Cb_b_tab [i] = private->Cb_b_tab [1024];
+      }
+      for (i = 1024 + 256; i < 2048 + 256; i++)
+      {
+	 private->Cr_r_tab [i] = private->Cr_r_tab [1024 + 255];
+	 private->Cr_g_tab [i] = private->Cr_g_tab [1024 + 255];
+	 private->Cb_g_tab [i] = private->Cb_g_tab [1024 + 255]; 
+	 private->Cb_b_tab [i] = private->Cb_b_tab [1024 + 255];
+      }
+
+      private->Cr_r_tab += 1024 + 128;
+      private->Cr_g_tab += 1024 + 128;
+      private->Cb_g_tab += 1024 + 128;
+      private->Cb_b_tab += 1024 + 128;
+   
+      /* 
+       *  Set up entries 0-255 in rgb-to-pixel value tables.
+       */
+      private->r_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
+      private->g_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
+      private->b_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
+      private->y_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
+
+      if (!private->r_table || !private->g_table
+	  || !private->b_table || !private->y_table)
+      {
+	 set_error (_("Out of memory."));
+	 return NULL;
+      }
+      
+      for (i = 0; i < 256; i++)
+      {
+	 private->r_table [i + 1024]
+	    = i >> (8 - number_of_bits_set(red_mask));
+	 private->r_table [i + 1024]
+	    <<= free_bits_at_bottom (red_mask);
+	 private->g_table [i + 1024]
+	    = i >> (8 - number_of_bits_set (green_mask));
+	 private->g_table [i + 1024]
+	    <<= free_bits_at_bottom (green_mask);
+	 private->b_table [i + 1024]
+	    <<= free_bits_at_bottom (blue_mask);
+	 private->b_table [i + 1024]
+	    = i >> (8 - number_of_bits_set (blue_mask));
+	 if (twopixels)
+	 {
+	    private->r_table [i + 1024] = ((private->r_table [i + 1024] << 16)
+					   | private->r_table [i + 1024]);
+	    private->g_table [i + 1024] = ((private->g_table [i + 1024] << 16)
+					   | private->g_table [i + 1024]);
+	    private->b_table [i + 1024] = ((private->b_table [i + 1024] << 16)
+					   | private->b_table [i + 1024]);
+	 }
+	 private->y_table [i + 1024] = (private->r_table [i + 1024]
+					| private->g_table [i + 1024]
+					| private->b_table [i + 1024]);
+      }
+
+      /*
+       * Spread out the values we have to the rest of the array so that
+       * we do not need to check for overflow.
+       */
+      for (i = 0; i < 1024; i++)
+      {
+	 private->r_table [i]              = private->r_table [1024];
+	 private->r_table [i + 1024 + 256] = private->r_table [1024 + 255];
+	 private->g_table [i]              = private->g_table [1024];
+	 private->g_table [i + 1024 + 256] = private->g_table [1024 + 255];
+	 private->b_table [i]              = private->b_table [1024];
+	 private->b_table [i + 1024 + 256] = private->b_table [1024 + 255];
+	 private->y_table [i]              = private->y_table [1024];
+	 private->y_table [i + 1024 + 256] = private->y_table [1024 + 255];
+      }
+
+      private->r_table += 1024;
+      private->g_table += 1024;
+      private->b_table += 1024;
+      private->y_table += 1024 + 128;
+
+      return render;
+   }
+   
+}
+
+void
+fiasco_renderer_delete (fiasco_renderer_t *renderer)
+/*
+ *  FIASCO renderer destructor:
+ *  Free memory of 'renderer' structure.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'renderer' is discarded.
+ */
+{
+   if (!renderer)
+      return;
+   else
+   {
+      renderer_private_t *private = (renderer_private_t *) renderer->private;
+
+      Free (private->Cr_g_tab - (1024 + 128));
+      Free (private->Cr_r_tab - (1024 + 128));
+      Free (private->Cb_g_tab - (1024 + 128));
+      Free (private->Cb_b_tab - (1024 + 128));
+      Free (private->r_table - 1024);
+      Free (private->g_table - 1024);
+      Free (private->b_table - 1024);
+      Free (private->y_table - (1024 + 128));
+
+      Free (private);
+      Free (renderer);
+   }
+}
+
+int
+fiasco_renderer_render (const fiasco_renderer_t *renderer,
+			unsigned char *ximage,
+			const fiasco_image_t *fiasco_image)
+{
+   if (!renderer)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "renderer");
+      return 0;
+   }
+   else
+      return renderer->render (renderer, ximage, fiasco_image);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+/*
+ *  Erik Corry's multi-byte dither routines.
+ *
+ *  The basic idea is that the Init generates all the necessary
+ *  tables.  The tables incorporate the information about the layout
+ *  of pixels in the XImage, so that it should be able to cope with
+ *  16-bit 24-bit (non-packed) and 32-bit (10-11 bits per
+ *  color!) screens.  At present it cannot cope with 24-bit packed
+ *  mode, since this involves getting down to byte level again. It is
+ *  assumed that the bits for each color are contiguous in the
+ *  longword.
+ * 
+ *  Writing to memory is done in shorts or ints. (Unfortunately, short
+ *  is not very fast on Alpha, so there is room for improvement
+ *  here). There is no dither time check for overflow - instead the
+ *  tables have slack at each end. This is likely to be faster than an
+ *  'if' test as many modern architectures are really bad at
+ *  ifs. Potentially, each '&&' causes a pipeline flush!
+ *
+ *  There is no shifting and fixed point arithmetic, as I really doubt
+ *  you can see the difference, and it costs. This may be just my
+ *  bias, since I heard that Intel is really bad at shifting.
+ */
+
+static int
+number_of_bits_set (unsigned long a)
+/*
+ *  How many 1 bits are there in the longword.
+ *  Low performance, do not call often.
+ */
+{
+   if (!a)
+      return 0;
+   if (a & 1)
+      return 1 + number_of_bits_set (a >> 1);
+   else
+      return (number_of_bits_set (a >> 1));
+}
+
+static int
+free_bits_at_top (unsigned long a)
+/*
+ *  How many 0 bits are there at most significant end of longword.
+ *  Low performance, do not call often.
+ */
+{
+   if(!a)				/* assume char is 8 bits */
+      return sizeof (unsigned long) * 8;
+   else if (((long) a) < 0l)		/* assume twos complement */
+      return 0;
+   else
+      return 1 + free_bits_at_top ( a << 1);
+}
+
+static int
+free_bits_at_bottom (unsigned long a)
+/*
+ *  How many 0 bits are there at least significant end of longword.
+ *  Low performance, do not call often.
+ */
+{
+   /* assume char is 8 bits */
+   if (!a)
+      return sizeof (unsigned long) * 8;
+   else if(((long) a) & 1l)
+      return 0;
+   else
+      return 1 + free_bits_at_bottom ( a >> 1);
+}
+
+static int 
+display_16_bit (const struct fiasco_renderer *this, unsigned char *ximage,
+		const fiasco_image_t *fiasco_image)
+/*
+ *  Convert 'image' to 16 bit color bitmap.
+ *  If 'double_resolution' is true then double image size in both directions.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'out[]'	is filled with dithered image
+ */
+{
+   const image_t      *image;
+   renderer_private_t *private;
+   byte_t	      *out;
+   
+   if (!this)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "this");
+      return 0;
+   }
+   if (!ximage)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
+      return 0;
+   }
+   if (!fiasco_image)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
+      return 0;
+   }
+
+   out 	   = (byte_t *) ximage;
+   image   = cast_image ((fiasco_image_t *) fiasco_image);
+   if (!image)
+      return 0;
+   private = (renderer_private_t *) this->private;
+   
+   if (image->color)
+   {
+      word_t 	   *cbptr, *crptr;	/* pointer to chroma bands */
+      word_t 	   *yptr;		/* pointers to lumincance band */
+      int     	    yval, crval, cbval;	/* pixel value in YCbCr color space */
+      int     	    R, G, B;		/* pixel value in RGB color space */
+      int     	    n;			/* pixel counter */
+      int     	    x, y;		/* pixel coordinates */
+      int 	   *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
+      unsigned int *r_table, *g_table, *b_table;
+
+      Cr_g_tab = private->Cr_g_tab;
+      Cr_r_tab = private->Cr_r_tab;
+      Cb_b_tab = private->Cb_b_tab;
+      Cb_g_tab = private->Cb_g_tab;
+      r_table  = private->r_table;
+      g_table  = private->g_table;
+      b_table  = private->b_table;
+      yptr     = image->pixels [Y];
+      cbptr    = image->pixels [Cb];
+      crptr    = image->pixels [Cr];
+
+      if (image->format == FORMAT_4_2_0)
+      {
+	 u_word_t *dst, *dst2;		/* pointers to dithered pixels */
+	 word_t	  *yptr2;		/* pointers to lumincance band */
+
+	 if (private->double_resolution)
+	 {
+	    yptr2 = yptr + image->width;
+	    dst   = (u_word_t *) out;
+	    dst2  = dst + 4 * image->width;
+	    for (y = image->height / 2; y; y--)
+	    {
+	       for (x = image->width / 2; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  crval = *crptr++ >> 4;
+		  cbval = *cbptr++ >> 4;
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  crval = *crptr++ / 16;
+		  cbval = *cbptr++ / 16;
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+	       
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+	       }
+	       memcpy (dst, dst - 2 * image->width,
+		       2 * image->width * sizeof (u_word_t));
+	       memcpy (dst2, dst2 - 2 * image->width,
+		       2 * image->width * sizeof (u_word_t));
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	       dst   += 3 * image->width * 2;
+	       dst2  += 3 * image->width * 2;
+	    }
+	 }
+	 else
+	 {
+	    yptr2 = yptr + image->width;
+	    dst  = (u_word_t *) out;
+	    dst2 = dst + image->width;
+	    
+	    for (y = image->height / 2; y; y--)
+	    {
+	       for (x = image->width / 2; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  crval = *crptr++ >> 4;
+		  cbval = *cbptr++ >> 4;
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  crval = *crptr++ / 16;
+		  cbval = *cbptr++ / 16;
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+	       
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+	       }
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	       dst   += image->width;
+	       dst2  += image->width;
+	    }
+	 }
+      }
+      else				/* 4:4:4 format */
+      {
+	 if (private->double_resolution)
+	 {
+	    unsigned int *dst;		/* pointer to dithered pixels */
+	    
+	    dst  = (unsigned int *) out;
+	    
+	    for (y = image->height; y; y--)
+	    {
+	       for (x = image->width; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  crval = *crptr++ >> 4;
+		  cbval = *cbptr++ >> 4;
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  crval = *crptr++ / 16;
+		  cbval = *cbptr++ / 16;
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+	       }
+	       memcpy (dst, dst - image->width,
+		       image->width * sizeof (unsigned int));
+	       dst += image->width;
+	    }
+	 }
+	 else
+	 {
+	    u_word_t *dst;		/* pointer to dithered pixels */
+
+	    dst  = (u_word_t *) out;
+	    
+	    for (n = image->width * image->height; n; n--)
+	    {
+#ifdef HAVE_SIGNED_SHIFT
+	       crval = *crptr++ >> 4;
+	       cbval = *cbptr++ >> 4;
+	       yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+	       crval = *crptr++ / 16;
+	       cbval = *cbptr++ / 16;
+	       yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+	       R = yval + Cr_r_tab [crval];
+	       G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+	       B = yval + Cb_b_tab [cbval];
+
+	       *dst++ = r_table [R] | g_table [G] | b_table [B];
+	    }
+	 }
+      }
+   }
+   else
+   {
+      unsigned int *dst;		/* pointer to dithered pixels */
+      word_t	   *src;		/* current pixel of frame */
+      unsigned int *y_table;
+
+      y_table = private->y_table;
+      dst     = (unsigned int *) out;
+      src     = image->pixels [GRAY];
+      
+      if (private->double_resolution)
+      {
+	 int x, y;			/* pixel coordinates */
+  	    
+	 for (y = image->height; y; y--)
+	 {
+	    for (x = image->width; x; x--)
+	    {
+	       int value;
+	       
+#ifdef HAVE_SIGNED_SHIFT
+	       value = y_table [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	       value = y_table [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+	       *dst++ = (value << 16) | value;
+	    }
+	    
+	    memcpy (dst, dst - image->width,
+		    image->width * sizeof (unsigned int));
+	    dst += image->width;
+	 }
+      }
+      else
+      {
+	 int n;				/* pixel counter */
+	 
+	 for (n = image->width * image->height / 2; n; n--, src += 2)
+#ifdef HAVE_SIGNED_SHIFT
+#	ifndef WORDS_BIGENDIAN
+	    *dst++ = (y_table [src [1] >> 4] << 16) | y_table [src [0] >> 4];
+#	else /* not WORDS_BIGENDIAN  */
+	    *dst++ = (y_table [src [0] >> 4] << 16) | y_table [src [1] >> 4];
+#	endif
+#else /* not HAVE_SIGNED_SHIFT */
+#	ifndef WORDS_BIGENDIAN
+	    *dst++ = (y_table [src [1] / 16] << 16) | y_table [src [0] / 16];
+#	else /* not WORDS_BIGENDIAN  */
+	    *dst++ = (y_table [src [0] / 16] << 16) | y_table [src [1] / 16];
+#	endif
+#endif /* not HAVE_SIGNED_SHIFT */
+      }
+   }
+
+   return 1;
+}
+
+static int 
+display_24_bit_bgr (const struct fiasco_renderer *this, unsigned char *ximage,
+		    const fiasco_image_t *fiasco_image)
+/*
+ *  Convert 'image' to 16 bit color bitmap.
+ *  If 'double_resolution' is true then double image size in both directions.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'out[]'	is filled with dithered image
+ */
+{
+   unsigned 	      *gray_clip = init_clipping ();
+   const image_t      *image;
+   renderer_private_t *private;
+   byte_t	      *out;
+
+   if (!gray_clip)
+      return 0;
+   if (!this)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "this");
+      return 0;
+   }
+   if (!ximage)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
+      return 0;
+   }
+   if (!fiasco_image)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
+      return 0;
+   }
+
+   out 	   = (byte_t *) ximage;
+   image   = cast_image ((fiasco_image_t *) fiasco_image);
+   if (!image)
+      return 0;
+   private = (renderer_private_t *) this->private;
+   
+   if (image->color)
+   {
+      word_t 	   *cbptr, *crptr;	/* pointer to chroma bands */
+      word_t 	   *yptr;		/* pointers to lumincance band */
+      int 	   *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
+      unsigned int *r_table, *g_table, *b_table;
+
+      Cr_g_tab = private->Cr_g_tab;
+      Cr_r_tab = private->Cr_r_tab;
+      Cb_b_tab = private->Cb_b_tab;
+      Cb_g_tab = private->Cb_g_tab;
+      r_table  = private->r_table;
+      g_table  = private->g_table;
+      b_table  = private->b_table;
+      yptr     = image->pixels [Y];
+      cbptr    = image->pixels [Cb];
+      crptr    = image->pixels [Cr];
+
+      if (image->format == FORMAT_4_2_0)
+      {
+	 if (private->double_resolution)
+	 {
+	    int		  yval1;	/* lumincance pixel */
+	    int 	  crval1, cbval1; /* chroma pixels */
+	    int		  yval2;	/* pixel in YCbCr color space */
+	    unsigned int  R1, G1, B1;	/* pixel in RGB color space */
+	    unsigned int  R2, G2, B2;	/* pixel in RGB color space */
+	    int		  x, y;		/* pixel counter */
+	    unsigned int *dst;		/* pointer to dithered pixels */
+	    unsigned int *dst2;		/* pointers to dithered pixels */
+	    word_t	 *yptr2;	/* pointers to lumincance band */
+	    
+	    dst   = (unsigned int *) out;
+	    dst2  = dst + (image->width >> 1) * 3 * 2;
+	    yptr2 = yptr + image->width;
+	    
+	    for (y = image->height >> 1; y; y--)
+	    {
+	       for (x = image->width >> 1; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B1 << 24);
+		  *dst++ = G1 | (R1 << 8) | (B2 << 16) | (G2 << 24);
+		  *dst++ = R2 | (B2 << 8) | (G2 << 16) | (R2 << 24);
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr2++ >> 4) + 128;
+		  yval2  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr2++  / 16 + 128;
+		  yval2  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst2++ = B1 | (G1 << 8) | (R1 << 16) | (B1 << 24);
+		  *dst2++ = G1 | (R1 << 8) | (B2 << 16) | (G2 << 24);
+		  *dst2++ = R2 | (B2 << 8) | (G2 << 16) | (R2 << 24);
+	       }
+	       memcpy (dst, dst - (image->width >> 1) * 3,
+		       (image->width >> 1) * 3 * sizeof (unsigned int));
+	       memcpy (dst2, dst2 - (image->width >> 1) * 3, 
+		       (image->width >> 1) * 3 * sizeof (unsigned int));
+	       dst   += (image->width >> 1) * 3 * 3;
+	       dst2  += (image->width >> 1) * 3 * 3;
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	    }
+	 }
+	 else
+	 {
+	    int		  yval1;	/* lumincance pixel */
+	    int 	  crval1, cbval1; /* chroma pixels */
+	    int		  yval2;	/* pixel in YCbCr color space */
+	    unsigned int  R1, G1, B1;	/* pixel in RGB color space */
+	    unsigned int  R2, G2, B2;	/* pixel in RGB color space */
+	    int		  x, y;		/* pixel counter */
+	    unsigned int *dst;		/* pointer to dithered pixels */
+	    unsigned int *dst2;		/* pointers to dithered pixels */
+	    word_t	 *yptr2;	/* pointers to lumincance band */
+	    
+	    dst   = (unsigned int *) out;
+	    dst2  = dst + (image->width >> 2) * 3;
+	    yptr2 = yptr + image->width;
+	    
+	    for (y = image->height >> 1; y; y--)
+	    {
+	       for (x = image->width >> 2; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B2 << 24);
+		  *dst   = G2 | (R2 << 8);
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr2++ >> 4) + 128;
+		  yval2  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr2++  / 16 + 128;
+		  yval2  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst2++ = B1 | (G1 << 8) | (R1 << 16) | (B2 << 24);
+		  *dst2   = G2 | (R2 << 8);
+	       
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  crval2 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+		  cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst++ |= (B1 << 16) | (G1 << 24);
+		  *dst++ = R1 | (B2 << 8) | (G2 << 16) | (R2 << 24);
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr2++ >> 4) + 128;
+		  yval2  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr2++  / 16 + 128;
+		  yval2  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst2++ |= (B1 << 16) | (G1 << 24);
+		  *dst2++ = R1 | (B2 << 8) | (G2 << 16) | (R2 << 24);
+	       }
+	       dst   += (image->width >> 2) * 3;
+	       dst2  += (image->width >> 2) * 3;
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	    }
+	 }
+      }
+      else				/* 4:4:4 format */
+      {
+	 if (private->double_resolution)
+	 {
+	    unsigned int R1, G1, B1;		/* pixel1 in RGB color space */
+	    unsigned int R2, G2, B2;		/* pixel2 in RGB color space */
+	    int		 yval1, crval1, cbval1;	/* pixel1 in YCbCr space */
+	    int		 yval2, crval2, cbval2;	/* pixel2 in YCbCr space */
+	    int		 x, y;			/* pixel counter */
+	    unsigned int *dst;		        /* dithered pixel pointer */
+	    
+	    dst = (unsigned int *) out;
+	    
+	    for (y = image->height; y; y--)
+	    {
+	       for (x = image->width >> 1; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  crval2 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+		  cbval2 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  crval2 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+		  cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				 + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval2]
+				 + Cb_g_tab [cbval2]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
+
+		  *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B1 << 24);
+		  *dst++ = G1 | (R1 << 8) | (B2 << 16) | (G2 << 24);
+		  *dst++ = R2 | (B2 << 8) | (G2 << 16) | (R2 << 24);
+	       }
+	       memcpy (dst, dst - 3 * (image->width >> 1),
+		       3 * (image->width >> 1) * sizeof (unsigned int));
+	       dst += 3 * (image->width >> 1);
+	    }
+	 }
+	 else
+	 {
+	    unsigned int R1, G1, B1;		/* pixel in RGB color space */
+	    unsigned int R2, G2, B2;		/* pixel in RGB color space */
+	    int		 yval1, crval1, cbval1;	/* pixel1 in YCbCr space */
+	    int		 yval2, crval2, cbval2;	/* pixel2 in YCbCr space */
+	    int		 n;			/* pixel counter */
+	    unsigned int *dst;		        /* dithered pixel pointer */
+	    
+	    dst = (unsigned int *) out;
+	    
+	    for (n = (image->width * image->height) >> 2; n; n--)
+	    {
+#ifdef HAVE_SIGNED_SHIFT
+	       yval1  = (*yptr++ >> 4) + 128;
+	       yval2  = (*yptr++ >> 4) + 128;
+	       crval1 = *crptr++ >> 4;
+	       crval2 = *crptr++ >> 4;
+	       cbval1 = *cbptr++ >> 4;
+	       cbval2 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+	       yval1  = *yptr++  / 16 + 128;
+	       yval2  = *yptr++  / 16 + 128;
+	       crval1 = *crptr++ / 16;
+	       crval2 = *crptr++ / 16;
+	       cbval1 = *cbptr++ / 16;
+	       cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+	       G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
+	       B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+	       R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
+	       G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
+	       B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
+
+	       *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B2 << 24);
+	       *dst   = G2 | (R2 << 8);
+
+#ifdef HAVE_SIGNED_SHIFT
+	       yval1  = (*yptr++ >> 4) + 128;
+	       yval2  = (*yptr++ >> 4) + 128;
+	       crval1 = *crptr++ >> 4;
+	       crval2 = *crptr++ >> 4;
+	       cbval1 = *cbptr++ >> 4;
+	       cbval2 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+	       yval1  = *yptr++  / 16 + 128;
+	       yval2  = *yptr++  / 16 + 128;
+	       crval1 = *crptr++ / 16;
+	       crval2 = *crptr++ / 16;
+	       cbval1 = *cbptr++ / 16;
+	       cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+	       G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
+	       B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+	       R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
+	       G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
+	       B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
+
+	       *dst++ |= (B1 << 16) | (G1 << 24);
+	       *dst++ = R1 | (B2 << 8) | (G2 << 16) | (R2 << 24);
+	    }
+	 }
+      }
+   }
+   else
+   {
+      unsigned int *dst;		/* pointer to dithered pixels */
+      word_t	   *src;		/* current pixel of frame */
+      unsigned int *y_table;
+
+      y_table = private->y_table;
+      dst     = (unsigned int *) out;
+      src     = image->pixels [GRAY];
+
+      if (private->double_resolution)
+      {
+	 int	   x, y;		/* pixel counter */
+	 unsigned *shift_clipping = gray_clip + 128;
+
+	 for (y = image->height; y; y--)
+	 {
+	    for (x = image->width >> 1; x; x--)
+	    {
+	       unsigned int val1, val2;
+#ifdef HAVE_SIGNED_SHIFT
+	       val1 = shift_clipping [*src++ >> 4];
+	       val2 = shift_clipping [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	       val1 = shift_clipping [*src++ / 16];
+	       val2 = shift_clipping [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       *dst++ = val1 | (val1 << 8) | (val1 << 16) | (val1 << 24);
+	       *dst++ = val1 | (val1 << 8) | (val2 << 16) | (val2 << 24); 
+	       *dst++ = val2 | (val2 << 8) | (val2 << 16) | (val2 << 24);
+	    }
+
+	    memcpy (dst, dst - 3 * (image->width >> 1),
+		    3 * (image->width >> 1) * sizeof (unsigned int));
+	    dst += 3 * (image->width >> 1);
+	 }
+      }
+      else
+      {
+	 int	   n;			/* pixel counter */
+	 unsigned *shift_clipping = gray_clip + 128;
+
+	 for (n = (image->width * image->height) >> 2; n; n--)
+	 {
+	    unsigned int val1, val2;
+
+#ifdef HAVE_SIGNED_SHIFT
+	    val1 = shift_clipping [*src++ >> 4];
+	    val2 = shift_clipping [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	    val1 = shift_clipping [*src++ / 16];
+	    val2 = shift_clipping [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	    *dst++ = val1 | (val1 << 8)
+		     | (val1 << 16) | (val2 << 24);  /* RGBR */
+	    *dst   = val2 | (val2 << 8);             /* GB-- */
+
+#ifdef HAVE_SIGNED_SHIFT
+	    val1 = shift_clipping [*src++ >> 4];
+	    val2 = shift_clipping [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	    val1 = shift_clipping [*src++ / 16];
+	    val2 = shift_clipping [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+	    
+	    *dst++ |= (val1 << 16) | (val1 << 24);   /* --RG */
+	    *dst++  = val1 | (val2 << 8)
+		      | (val2 << 16) | (val2 << 24); /* BRGB */
+	 }
+      }
+   }
+   
+   return 1;
+}
+
+static int 
+display_24_bit_rgb (const struct fiasco_renderer *this, unsigned char *ximage,
+		    const fiasco_image_t *fiasco_image)
+/*
+ *  Convert 'image' to 16 bit color bitmap.
+ *  If 'double_resolution' is true then double image size in both directions.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'out[]'	is filled with dithered image
+ */
+{
+   unsigned 	      *gray_clip = init_clipping ();
+   const image_t      *image;
+   renderer_private_t *private;
+   byte_t	      *out;
+
+   if (!gray_clip)
+      return 0;
+   if (!this)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "this");
+      return 0;
+   }
+   if (!ximage)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
+      return 0;
+   }
+   if (!fiasco_image)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
+      return 0;
+   }
+
+   out 	   = (byte_t *) ximage;
+   image   = cast_image ((fiasco_image_t *) fiasco_image);
+   if (!image)
+      return 0;
+   private = (renderer_private_t *) this->private;
+   
+   if (image->color)
+   {
+      word_t 	   *cbptr, *crptr;	/* pointer to chroma bands */
+      word_t 	   *yptr;		/* pointers to lumincance band */
+      int 	   *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
+      unsigned int *r_table, *g_table, *b_table;
+
+      Cr_g_tab = private->Cr_g_tab;
+      Cr_r_tab = private->Cr_r_tab;
+      Cb_b_tab = private->Cb_b_tab;
+      Cb_g_tab = private->Cb_g_tab;
+      r_table  = private->r_table;
+      g_table  = private->g_table;
+      b_table  = private->b_table;
+      yptr     = image->pixels [Y];
+      cbptr    = image->pixels [Cb];
+      crptr    = image->pixels [Cr];
+
+      if (image->format == FORMAT_4_2_0)
+      {
+	 if (private->double_resolution)
+	 {
+	    int		  yval1;	/* lumincance pixel */
+	    int 	  crval1, cbval1; /* chroma pixels */
+	    int		  yval2;	/* pixel in YCbCr color space */
+	    unsigned int  R1, G1, B1;	/* pixel in RGB color space */
+	    unsigned int  R2, G2, B2;	/* pixel in RGB color space */
+	    int		  x, y;		/* pixel counter */
+	    unsigned int *dst;		/* pointer to dithered pixels */
+	    unsigned int *dst2;		/* pointers to dithered pixels */
+	    word_t	 *yptr2;	/* pointers to lumincance band */
+	    
+	    dst   = (unsigned int *) out;
+	    dst2  = dst + (image->width >> 1) * 3 * 2;
+	    yptr2 = yptr + image->width;
+	    
+	    for (y = image->height >> 1; y; y--)
+	    {
+	       for (x = image->width >> 1; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R1 << 24);
+		  *dst++ = G1 | (B1 << 8) | (R2 << 16) | (G2 << 24);
+		  *dst++ = B2 | (R2 << 8) | (G2 << 16) | (B2 << 24);
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr2++ >> 4) + 128;
+		  yval2  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr2++  / 16 + 128;
+		  yval2  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst2++ = R1 | (G1 << 8) | (B1 << 16) | (R1 << 24);
+		  *dst2++ = G1 | (B1 << 8) | (R2 << 16) | (G2 << 24);
+		  *dst2++ = B2 | (R2 << 8) | (G2 << 16) | (B2 << 24);
+	       }
+	       memcpy (dst, dst - (image->width >> 1) * 3,
+		       (image->width >> 1) * 3 * sizeof (unsigned int));
+	       memcpy (dst2, dst2 - (image->width >> 1) * 3, 
+		       (image->width >> 1) * 3 * sizeof (unsigned int));
+	       dst   += (image->width >> 1) * 3 * 3;
+	       dst2  += (image->width >> 1) * 3 * 3;
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	    }
+	 }
+	 else
+	 {
+	    int		  yval1;	/* lumincance pixel */
+	    int 	  crval1, cbval1; /* chroma pixels */
+	    int		  yval2;	/* pixel in YCbCr color space */
+	    unsigned int  R1, G1, B1;	/* pixel in RGB color space */
+	    unsigned int  R2, G2, B2;	/* pixel in RGB color space */
+	    int		  x, y;		/* pixel counter */
+	    unsigned int *dst;		/* pointer to dithered pixels */
+	    unsigned int *dst2;		/* pointers to dithered pixels */
+	    word_t	 *yptr2;	/* pointers to lumincance band */
+	    
+	    dst   = (unsigned int *) out;
+	    dst2  = dst + (image->width >> 2) * 3;
+	    yptr2 = yptr + image->width;
+	    
+	    for (y = image->height >> 1; y; y--)
+	    {
+	       for (x = image->width >> 2; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R2 << 24);
+		  *dst   = G2 | (B2 << 8);
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr2++ >> 4) + 128;
+		  yval2  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr2++  / 16 + 128;
+		  yval2  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst2++ = R1 | (G1 << 8) | (B1 << 16) | (R2 << 24);
+		  *dst2   = G2 | (B2 << 8);
+	       
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  crval2 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+		  cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst++ |= (R1 << 16) | (G1 << 24);
+		  *dst++ = B1 | (R2 << 8) | (G2 << 16) | (B2 << 24);
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr2++ >> 4) + 128;
+		  yval2  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr2++  / 16 + 128;
+		  yval2  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
+
+		  *dst2++ |= (R1 << 16) | (G1 << 24);
+		  *dst2++ = B1 | (R2 << 8) | (G2 << 16) | (B2 << 24);
+	       }
+	       dst   += (image->width >> 2) * 3;
+	       dst2  += (image->width >> 2) * 3;
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	    }
+	 }
+      }
+      else				/* 4:4:4 format */
+      {
+	 if (private->double_resolution)
+	 {
+	    unsigned int R1, G1, B1;		/* pixel1 in RGB color space */
+	    unsigned int R2, G2, B2;		/* pixel2 in RGB color space */
+	    int		 yval1, crval1, cbval1;	/* pixel1 in YCbCr space */
+	    int		 yval2, crval2, cbval2;	/* pixel2 in YCbCr space */
+	    int		 x, y;			/* pixel counter */
+	    unsigned int *dst;		        /* dithered pixel pointer */
+	    
+	    dst = (unsigned int *) out;
+	    
+	    for (y = image->height; y; y--)
+	    {
+	       for (x = image->width >> 1; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  yval1  = (*yptr++ >> 4) + 128;
+		  yval2  = (*yptr++ >> 4) + 128;
+		  crval1 = *crptr++ >> 4;
+		  crval2 = *crptr++ >> 4;
+		  cbval1 = *cbptr++ >> 4;
+		  cbval2 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval1  = *yptr++  / 16 + 128;
+		  yval2  = *yptr++  / 16 + 128;
+		  crval1 = *crptr++ / 16;
+		  crval2 = *crptr++ / 16;
+		  cbval1 = *cbptr++ / 16;
+		  cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  
+		  R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+		  G1 = gray_clip [yval1 + Cr_g_tab [crval1]
+				  + Cb_g_tab [cbval1]];
+		  B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+		  R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
+		  G2 = gray_clip [yval2 + Cr_g_tab [crval2]
+				  + Cb_g_tab [cbval2]];
+		  B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
+
+		  *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R1 << 24);
+		  *dst++ = G1 | (B1 << 8) | (R2 << 16) | (G2 << 24);
+		  *dst++ = B2 | (R2 << 8) | (G2 << 16) | (B2 << 24);
+	       }
+	       memcpy (dst, dst - 3 * (image->width >> 1),
+		       3 * (image->width >> 1) * sizeof (unsigned int));
+	       dst += 3 * (image->width >> 1);
+	    }
+	 }
+	 else
+	 {
+	    unsigned int R1, G1, B1;		/* pixel in RGB color space */
+	    unsigned int R2, G2, B2;		/* pixel in RGB color space */
+	    int		 yval1, crval1, cbval1;	/* pixel1 in YCbCr space */
+	    int		 yval2, crval2, cbval2;	/* pixel2 in YCbCr space */
+	    int		 n;			/* pixel counter */
+	    unsigned int *dst;		        /* dithered pixel pointer */
+	    
+	    dst = (unsigned int *) out;
+	    
+	    for (n = (image->width * image->height) >> 2; n; n--)
+	    {
+#ifdef HAVE_SIGNED_SHIFT
+	       yval1  = (*yptr++ >> 4) + 128;
+	       yval2  = (*yptr++ >> 4) + 128;
+	       crval1 = *crptr++ >> 4;
+	       crval2 = *crptr++ >> 4;
+	       cbval1 = *cbptr++ >> 4;
+	       cbval2 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+	       yval1  = *yptr++  / 16 + 128;
+	       yval2  = *yptr++  / 16 + 128;
+	       crval1 = *crptr++ / 16;
+	       crval2 = *crptr++ / 16;
+	       cbval1 = *cbptr++ / 16;
+	       cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+	       G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
+	       B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+	       R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
+	       G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
+	       B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
+
+	       *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R2 << 24);
+	       *dst   = G2 | (B2 << 8);
+
+#ifdef HAVE_SIGNED_SHIFT
+	       yval1  = (*yptr++ >> 4) + 128;
+	       yval2  = (*yptr++ >> 4) + 128;
+	       crval1 = *crptr++ >> 4;
+	       crval2 = *crptr++ >> 4;
+	       cbval1 = *cbptr++ >> 4;
+	       cbval2 = *cbptr++ >> 4;
+#else /* not HAVE_SIGNED_SHIFT */
+	       yval1  = *yptr++  / 16 + 128;
+	       yval2  = *yptr++  / 16 + 128;
+	       crval1 = *crptr++ / 16;
+	       crval2 = *crptr++ / 16;
+	       cbval1 = *cbptr++ / 16;
+	       cbval2 = *cbptr++ / 16;
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
+	       G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
+	       B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
+	       R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
+	       G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
+	       B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
+
+	       *dst++ |= (R1 << 16) | (G1 << 24);
+	       *dst++ = B1 | (R2 << 8) | (G2 << 16) | (B2 << 24);
+	    }
+	 }
+      }
+   }
+   else
+   {
+      unsigned int *dst;		/* pointer to dithered pixels */
+      word_t	   *src;		/* current pixel of frame */
+      unsigned int *y_table;
+
+      y_table = private->y_table;
+      dst     = (unsigned int *) out;
+      src     = image->pixels [GRAY];
+
+      if (private->double_resolution)
+      {
+	 int	   x, y;		/* pixel counter */
+	 unsigned *shift_clipping = gray_clip + 128;
+
+	 for (y = image->height; y; y--)
+	 {
+	    for (x = image->width >> 1; x; x--)
+	    {
+	       unsigned int val1, val2;
+#ifdef HAVE_SIGNED_SHIFT
+	       val1 = shift_clipping [*src++ >> 4];
+	       val2 = shift_clipping [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	       val1 = shift_clipping [*src++ / 16];
+	       val2 = shift_clipping [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	       *dst++ = val1 | (val1 << 8) | (val1 << 16) | (val1 << 24);
+	       *dst++ = val1 | (val1 << 8) | (val2 << 16) | (val2 << 24); 
+	       *dst++ = val2 | (val2 << 8) | (val2 << 16) | (val2 << 24);
+	    }
+
+	    memcpy (dst, dst - 3 * (image->width >> 1),
+		    3 * (image->width >> 1) * sizeof (unsigned int));
+	    dst += 3 * (image->width >> 1);
+	 }
+      }
+      else
+      {
+	 int	   n;			/* pixel counter */
+	 unsigned *shift_clipping = gray_clip + 128;
+
+	 for (n = (image->width * image->height) >> 2; n; n--)
+	 {
+	    unsigned int val1, val2;
+
+#ifdef HAVE_SIGNED_SHIFT
+	    val1 = shift_clipping [*src++ >> 4];
+	    val2 = shift_clipping [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	    val1 = shift_clipping [*src++ / 16];
+	    val2 = shift_clipping [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+
+	    *dst++ = val1 | (val1 << 8)
+		     | (val1 << 16) | (val2 << 24);  /* RGBR */
+	    *dst   = val2 | (val2 << 8);             /* GB-- */
+
+#ifdef HAVE_SIGNED_SHIFT
+	    val1 = shift_clipping [*src++ >> 4];
+	    val2 = shift_clipping [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	    val1 = shift_clipping [*src++ / 16];
+	    val2 = shift_clipping [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+	    
+	    *dst++ |= (val1 << 16) | (val1 << 24);   /* --RG */
+	    *dst++  = val1 | (val2 << 8)
+		      | (val2 << 16) | (val2 << 24); /* BRGB */
+	 }
+      }
+   }
+   
+   return 1;
+}
+
+static int 
+display_32_bit (const struct fiasco_renderer *this, unsigned char *ximage,
+		const fiasco_image_t *fiasco_image)
+/*
+ *  Convert 'image' to 16 bit color bitmap.
+ *  If 'double_resolution' is true then double image size in both directions.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'out[]'	is filled with dithered image
+ */
+{
+   const image_t      *image;
+   renderer_private_t *private;
+   byte_t	      *out;
+   
+   if (!this)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "this");
+      return 0;
+   }
+   if (!ximage)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
+      return 0;
+   }
+   if (!fiasco_image)
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
+      return 0;
+   }
+
+   out 	   = (byte_t *) ximage;
+   private = (renderer_private_t *) this->private;
+   image   = cast_image ((fiasco_image_t *) fiasco_image);
+   if (!image)
+      return 0;
+   
+   if (image->color)
+   {
+      word_t 	   *cbptr, *crptr;	/* pointer to chroma bands */
+      word_t 	   *yptr;		/* pointers to lumincance band */
+      int     	    yval, crval, cbval;	/* pixel value in YCbCr color space */
+      int     	    R, G, B;		/* pixel value in RGB color space */
+      int     	    n;			/* pixel counter */
+      int     	    x, y;		/* pixel coordinates */
+      int 	   *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
+      unsigned int *r_table, *g_table, *b_table;
+
+      Cr_g_tab = private->Cr_g_tab;
+      Cr_r_tab = private->Cr_r_tab;
+      Cb_b_tab = private->Cb_b_tab;
+      Cb_g_tab = private->Cb_g_tab;
+      r_table  = private->r_table;
+      g_table  = private->g_table;
+      b_table  = private->b_table;
+      yptr  = image->pixels [Y];
+      cbptr = image->pixels [Cb];
+      crptr = image->pixels [Cr];
+
+      if (image->format == FORMAT_4_2_0)
+      {
+	 unsigned int	*dst, *dst2;	/* pointers to dithered pixels */
+	 word_t		*yptr2;		/* pointers to lumincance band */
+
+	 if (private->double_resolution)
+	 {
+	    yptr2 = yptr + image->width;
+	    dst  = (unsigned int *) out;
+	    dst2 = dst + 4 * image->width;
+	    for (y = image->height / 2; y; y--)
+	    {
+	       for (x = image->width / 2; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  crval = *crptr++ >> 4;
+		  cbval = *cbptr++ >> 4;
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  crval = *crptr++ / 16;
+		  cbval = *cbptr++ / 16;
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+	       
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+	       }
+	       memcpy (dst, dst - 2 * image->width,
+		       2 * image->width * sizeof (unsigned int));
+	       memcpy (dst2, dst2 - 2 * image->width,
+		       2 * image->width * sizeof (unsigned int));
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	       dst   += 3 * image->width * 2;
+	       dst2  += 3 * image->width * 2;
+	    }
+	 }
+	 else
+	 {
+	    yptr2 = yptr + image->width;
+	    dst   = (unsigned int *) out;
+	    dst2  = dst + image->width;
+	    
+	    for (y = image->height / 2; y; y--)
+	    {
+	       for (x = image->width / 2; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  crval = *crptr++ >> 4;
+		  cbval = *cbptr++ >> 4;
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  crval = *crptr++ / 16;
+		  cbval = *cbptr++ / 16;
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+	       
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+
+#ifdef HAVE_SIGNED_SHIFT
+		  yval  = (*yptr2++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  yval  = *yptr2++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  *dst2++ = r_table [R] | g_table [G] | b_table [B];
+	       }
+	       yptr  += image->width;
+	       yptr2 += image->width;
+	       dst   += image->width;
+	       dst2  += image->width;
+	    }
+	 }
+      }
+      else				/* 4:4:4 format */
+      {
+	 if (private->double_resolution)
+	 {
+	    unsigned int *dst;		/* pointer to dithered pixels */
+	    
+	    dst = (unsigned int *) out;
+	    
+	    for (y = image->height; y; y--)
+	    {
+	       for (x = image->width; x; x--)
+	       {
+#ifdef HAVE_SIGNED_SHIFT
+		  crval = *crptr++ >> 4;
+		  cbval = *cbptr++ >> 4;
+		  yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+		  crval = *crptr++ / 16;
+		  cbval = *cbptr++ / 16;
+		  yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+		  R = yval + Cr_r_tab [crval];
+		  G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+		  B = yval + Cb_b_tab [cbval];
+		  
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+		  *dst++ = r_table [R] | g_table [G] | b_table [B];
+	       }
+	       memcpy (dst, dst - 2 * image->width,
+		       2 * image->width * sizeof (unsigned int));
+	       dst += image->width * 2;
+	    }
+	 }
+	 else
+	 {
+	    unsigned int *dst;		/* pointer to dithered pixels */
+
+	    dst  = (unsigned int *) out;
+	    
+	    for (n = image->width * image->height; n; n--)
+	    {
+#ifdef HAVE_SIGNED_SHIFT
+	       crval = *crptr++ >> 4;
+	       cbval = *cbptr++ >> 4;
+	       yval  = (*yptr++ >> 4) + 128;
+#else /* not HAVE_SIGNED_SHIFT */
+	       crval = *crptr++ / 16;
+	       cbval = *cbptr++ / 16;
+	       yval  = *yptr++  / 16 + 128;
+#endif /* not HAVE_SIGNED_SHIFT */
+	       R = yval + Cr_r_tab [crval];
+	       G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
+	       B = yval + Cb_b_tab [cbval];
+
+	       *dst++ = r_table [R] | g_table [G] | b_table [B];
+	    }
+	 }
+      }
+   }
+   else
+   {
+      unsigned int *dst;		/* pointer to dithered pixels */
+      word_t	   *src;		/* current pixel of frame */
+      unsigned int *y_table;
+
+      y_table = private->y_table;
+      dst     = (unsigned int *) out;
+      src     = image->pixels [GRAY];
+      
+      if (private->double_resolution)
+      {
+	 int x, y;			/* pixel coordinates */
+	 
+	 for (y = image->height; y; y--)
+	 {
+	    for (x = image->width; x; x--)
+	    {
+	       int value;
+
+#ifdef HAVE_SIGNED_SHIFT
+	       value = y_table [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	       value = y_table [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+	       *dst++ = value;
+	       *dst++ = value;
+	    }
+
+	    memcpy (dst, dst - 2 * image->width,
+		    2 * image->width * sizeof (unsigned int));
+	    dst += 2 * image->width;
+	 }
+      }
+      else
+      {
+	 int n;				/* pixel counter */
+	 
+	 for (n = image->width * image->height; n; n--)
+#ifdef HAVE_SIGNED_SHIFT
+	    *dst++ = y_table [*src++ >> 4];
+#else /* not HAVE_SIGNED_SHIFT */
+	    *dst++ = y_table [*src++ / 16];
+#endif /* not HAVE_SIGNED_SHIFT */
+      }
+   }
+   
+   return 1;
+}
+
+
+ 
diff --git a/converter/other/fiasco/lib/dither.h b/converter/other/fiasco/lib/dither.h
new file mode 100644
index 00000000..71f9d3c3
--- /dev/null
+++ b/converter/other/fiasco/lib/dither.h
@@ -0,0 +1,27 @@
+/*
+ *  dither.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _DITHER_H
+#define _DITHER_H
+
+typedef struct renderer_private
+{
+   int 	       	*Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
+   unsigned int *r_table, *g_table, *b_table, *y_table;
+   bool_t	double_resolution;
+} renderer_private_t;
+
+#endif /* _DITHER_H */
diff --git a/converter/other/fiasco/lib/error.c b/converter/other/fiasco/lib/error.c
new file mode 100644
index 00000000..b858badf
--- /dev/null
+++ b/converter/other/fiasco/lib/error.c
@@ -0,0 +1,326 @@
+/*
+ *  error.c:		Error handling
+ *
+ *  Written by:		Stefan Frank
+ *			Ullrich Hafner
+ *  
+ *  Credits:	Modelled after variable argument routines from Jef
+ *		Poskanzer's pbmplus package. 
+ *
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+
+    "int dummy = " change to int dummy; dummy =" for Netpbm to avoid 
+    unused variable warning.
+
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#define _ERROR_C
+
+#include "config.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+#if STDC_HEADERS
+#	include <stdarg.h>
+#	define VA_START(args, lastarg) va_start(args, lastarg)
+#else  /* not STDC_HEADERS */
+#	include <varargs.h>
+#	define VA_START(args, lastarg) va_start(args)
+#endif /* not STDC_HEADERS */
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#if HAVE_SETJMP_H
+#	include <setjmp.h>
+#endif /* HAVE_SETJMP_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "misc.h"
+#include "fiasco.h"
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+static fiasco_verbosity_e  verboselevel  = FIASCO_SOME_VERBOSITY;
+static char 	      	  *error_message = NULL;
+
+#if HAVE_SETJMP_H
+jmp_buf env;
+#endif /* HAVE_SETJMP_H */
+
+/*****************************************************************************
+
+			       public code
+  
+*****************************************************************************/
+
+void
+set_error (const char *format, ...)
+/*
+ *  Set error text to given string.
+ */
+{
+   va_list     args;
+   unsigned    len = 0;
+   const char *str = format;
+   
+   VA_START (args, format);
+
+   len = strlen (format);
+   while ((str = strchr (str, '%')))
+   {
+      str++;
+      if (*str == 's')
+      {
+	 char *vstring = va_arg (args, char *);
+	 len += strlen (vstring);
+      }
+      else if (*str == 'd')
+      {
+	 int dummy;
+     dummy = va_arg (args, int);
+	 len += 10;
+      }
+      else if (*str == 'c')
+      {
+	 int dummy;
+     dummy = va_arg (args, int);
+	 len += 1;
+      }
+      else
+	 return;
+      str++;
+   }
+   va_end(args);
+
+   VA_START (args, format);
+
+   if (error_message)
+      Free (error_message);
+   error_message = Calloc (len, sizeof (char));
+   
+#if HAVE_VPRINTF
+   vsprintf (error_message, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+
+   va_end (args);
+}
+
+void
+error (const char *format, ...)
+/*
+ *  Set error text to given string.
+ */
+{
+   va_list     args;
+   unsigned    len = 0;
+   const char *str = format;
+   
+   VA_START (args, format);
+
+   len = strlen (format);
+   while ((str = strchr (str, '%')))
+   {
+      str++;
+      if (*str == 's')
+      {
+	 char *vstring = va_arg (args, char *);
+	 len += strlen (vstring);
+      }
+      else if (*str == 'd')
+      {
+	 int dummy;
+     dummy = va_arg (args, int);
+	 len += 10;
+      }
+      else if (*str == 'c')
+      {
+	 int dummy;
+     dummy = va_arg (args, int);
+	 len += 1;
+      }
+      else
+      {
+#if HAVE_SETJMP_H
+	 longjmp (env, 1);
+#else /* not HAVE_SETJMP_H */
+	 exit (1);
+#endif /* HAVE_SETJMP_H */
+      };
+      
+      str++;
+   }
+   va_end(args);
+
+   VA_START (args, format);
+
+   if (error_message)
+      Free (error_message);
+   error_message = Calloc (len, sizeof (char));
+   
+#if HAVE_VPRINTF
+   vsprintf (error_message, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+
+   va_end (args);
+   
+#if HAVE_SETJMP_H
+   longjmp (env, 1);
+#else /* not HAVE_SETJMP_H */
+   exit (1);
+#endif /* HAVE_SETJMP_H */
+}
+
+const char *
+fiasco_get_error_message (void)
+/*
+ *  Return value:
+ *	Last error message of FIASCO library.
+ */
+{
+   return error_message ? error_message : "";
+}
+
+const char *
+get_system_error (void)
+{
+   return strerror (errno);
+}
+
+void
+file_error (const char *filename)
+/*
+ *  Print file error message and exit.
+ *
+ *  No return value.
+ */
+{
+   error ("File `%s': I/O Error - %s.", filename, get_system_error ());
+}
+
+void 
+warning (const char *format, ...)
+/*
+ *  Issue a warning and continue execution.
+ *
+ *  No return value.
+ */
+{
+   va_list	args;
+
+   VA_START (args, format);
+
+   if (verboselevel == FIASCO_NO_VERBOSITY)
+      return;
+	
+   fprintf (stderr, "Warning: ");
+#if HAVE_VPRINTF
+   vfprintf (stderr, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+   fputc ('\n', stderr);
+
+   va_end (args);
+}
+
+void 
+message (const char *format, ...)
+/*
+ *  Print a message to stderr.
+ */
+{
+   va_list args;
+
+   VA_START (args, format);
+
+   if (verboselevel == FIASCO_NO_VERBOSITY)
+      return;
+
+#if HAVE_VPRINTF
+   vfprintf (stderr, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+   fputc ('\n', stderr);
+   va_end (args);
+}
+
+void 
+debug_message (const char *format, ...)
+/*
+ *  Print a message to stderr.
+ */
+{
+   va_list args;
+
+   VA_START (args, format);
+
+   if (verboselevel < FIASCO_ULTIMATE_VERBOSITY)
+      return;
+
+   fprintf (stderr, "*** ");
+#if HAVE_VPRINTF
+   vfprintf (stderr, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+   fputc ('\n', stderr);
+   va_end (args);
+}
+
+void
+info (const char *format, ...)
+/*
+ *  Print a message to stderr. Do not append a newline.
+ */
+{
+   va_list args;
+
+   VA_START (args, format);
+
+   if (verboselevel == FIASCO_NO_VERBOSITY)
+      return;
+
+#if HAVE_VPRINTF
+   vfprintf (stderr, format, args);
+#elif HAVE_DOPRNT
+   _doprnt (format, args, stderr);
+#endif /* HAVE_DOPRNT */
+   fflush (stderr);
+   va_end (args);
+}
+
+void
+fiasco_set_verbosity (fiasco_verbosity_e level)
+{
+   verboselevel = level;
+}
+
+fiasco_verbosity_e
+fiasco_get_verbosity (void)
+{
+   return verboselevel;
+}
diff --git a/converter/other/fiasco/lib/error.h b/converter/other/fiasco/lib/error.h
new file mode 100644
index 00000000..288b25f4
--- /dev/null
+++ b/converter/other/fiasco/lib/error.h
@@ -0,0 +1,39 @@
+/*
+ *  error.h
+ *  
+ *  Written by:     Stefan Frank
+ *          Ullrich Hafner
+ *
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+#ifndef ERROR_H_INCLUDED
+#define ERROR_H_INCLUDED
+
+void
+set_error (const char *format, ...);
+void
+error (const char *format, ...);
+void
+file_error (const char *filename);
+void
+message (const char *format, ...);
+void 
+debug_message (const char *format, ...);
+void
+warning (const char *format, ...);
+void 
+info (const char *format, ...);
+const char *
+get_system_error (void);
+
+#include <setjmp.h>
+extern jmp_buf env;
+
+#define try         if (setjmp (env) == 0)
+#define catch           else
+
+#include <assert.h>
+
+#endif
diff --git a/converter/other/fiasco/lib/image.c b/converter/other/fiasco/lib/image.c
new file mode 100644
index 00000000..019ba03c
--- /dev/null
+++ b/converter/other/fiasco/lib/image.c
@@ -0,0 +1,512 @@
+/*
+ *  image.c:		Input and output of PNM images.
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/15 17:21:30 $
+ *  $Author: hafner $
+ *  $Revision: 5.2 $
+ *  $State: Exp $
+ */
+
+#include "pnm.h"
+
+#include <string.h>
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "fiasco.h"
+#include "misc.h"
+#include "image.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+init_chroma_tables (void);
+
+/*****************************************************************************
+
+				local variables
+  
+*****************************************************************************/
+static int *Cr_r_tab = NULL;
+static int *Cr_g_tab = NULL;
+static int *Cb_g_tab = NULL;
+static int *Cb_b_tab = NULL;
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+fiasco_image_t *
+fiasco_image_new (const char *filename)
+/*
+ *  FIASCO image constructor.
+ *  Allocate memory for the FIASCO image structure and
+ *  load the specified image `filename'. The image has to be in
+ *  raw pgm or ppm format.
+ *
+ *  Return value:
+ *	pointer to the new image structure
+ *	or NULL in case of an error
+ */
+{
+   try
+   {
+      fiasco_image_t *image = Calloc (1, sizeof (fiasco_image_t));
+
+      image->private 	= read_image (filename);
+      image->delete  	= fiasco_image_delete;
+      image->get_width  = fiasco_image_get_width;
+      image->get_height = fiasco_image_get_height;
+      image->is_color  	= fiasco_image_is_color;
+
+      return image;
+   }
+   catch
+   {
+      return NULL;
+   }
+}
+
+void
+fiasco_image_delete (fiasco_image_t *image)
+/*
+ *  FIASCO image destructor.
+ *  Free memory of FIASCO image struct.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'image' is discarded.
+ */
+{
+   image_t *this = cast_image (image);
+
+   if (!this)
+      return;
+
+   try
+   {
+      free_image (this);
+   }
+   catch
+   {
+      return;
+   }
+}
+
+unsigned
+fiasco_image_get_width (fiasco_image_t *image)
+{
+   image_t *this = cast_image (image);
+
+   if (!this)
+      return 0;
+   else
+      return this->width;
+}
+
+unsigned
+fiasco_image_get_height (fiasco_image_t *image)
+{
+   image_t *this = cast_image (image);
+
+   if (!this)
+      return 0;
+   else
+      return this->width;
+}
+
+int
+fiasco_image_is_color (fiasco_image_t *image)
+{
+   image_t *this = cast_image (image);
+
+   if (!this)
+      return 0;
+   else
+      return this->color;
+}
+
+image_t *
+cast_image (fiasco_image_t *image)
+/*
+ *  Cast pointer `image' to type image_t.
+ *  Check whether `image' is a valid object of type image_t.
+ *
+ *  Return value:
+ *	pointer to dfiasco_t struct on success
+ *      NULL otherwise
+ */
+{
+   image_t *this = (image_t *) image->private;
+   if (this)
+   {
+      if (!streq (this->id, "IFIASCO"))
+      {
+	 set_error (_("Parameter `image' doesn't match required type."));
+	 return NULL;
+      }
+   }
+   else
+   {
+      set_error (_("Parameter `%s' not defined (NULL)."), "image");
+   }
+
+   return this;
+}
+
+image_t *
+alloc_image (unsigned width, unsigned height, bool_t color, format_e format)
+/*
+ *  Image constructor:
+ *  Allocate memory for the image_t structure.
+ *  Image size is given by 'width' and 'height'.
+ *  If 'color' == YES then allocate memory for three color bands (Y, Cb, Cr).
+ *  otherwise just allocate memory for a grayscale image.
+ *  'format' specifies whether image pixels of color images
+ *  are stored in 4:4:4 or 4:2:0 format.
+ *
+ *  Return value:
+ *	pointer to the new image structure.
+ */
+{
+   image_t *image;
+   color_e band;
+
+   if ((width & 1) || (height & 1))
+      error ("Width and height of images must be even numbers.");
+   if (!color)
+      format = FORMAT_4_4_4;
+
+   image         	  = Calloc (1, sizeof (image_t));
+   image->width  	  = width;
+   image->height 	  = height;
+   image->color  	  = color;
+   image->format 	  = format;
+   image->reference_count = 1;
+   
+   strcpy (image->id, "IFIASCO");
+
+   for (band = first_band (color); band <= last_band (color); band++)
+      if (format == FORMAT_4_2_0 && band != Y)
+	 image->pixels [band] = Calloc ((width * height) >> 2,
+					sizeof (word_t));
+      else
+	 image->pixels [band] = Calloc (width * height, sizeof (word_t));
+   
+   return image;
+}
+
+image_t *
+clone_image (image_t *image)
+/*
+ *  Copy constructor:
+ *  Construct new image by copying the given `image'.
+ *
+ *  Return value:
+ *	pointer to the new image structure.
+ */
+{
+   image_t *new = alloc_image (image->width, image->height, image->color,
+			       image->format);
+   color_e band;
+   
+   for (band = first_band (new->color); band <= last_band (new->color); band++)
+      if (new->format == FORMAT_4_2_0 && band != Y)
+      {
+	 memcpy (new->pixels [band], image->pixels [band],
+		 ((new->width * new->height) >> 2) * sizeof (word_t));
+      }
+      else
+      {
+	 memcpy (new->pixels [band], image->pixels [band],
+		 new->width * new->height * sizeof (word_t));
+      }
+
+   return new;
+}
+
+void
+free_image (image_t *image)
+/*
+ *  Image destructor:
+ *  Free memory of 'image' struct and pixel data.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	structure 'image' is discarded.
+ */
+{
+   if (image != NULL)
+   {
+      if (--image->reference_count)
+	 return;			/* image is still referenced */
+      else
+      {
+	 color_e band;
+
+	 for (band  = first_band (image->color);
+	      band <= last_band (image->color); band++)
+	    if (image->pixels [band])
+	       Free (image->pixels [band]);
+	 Free (image);
+      }
+   }
+   else
+      warning ("Can't free image <NULL>.");
+}
+
+
+static void 
+read_image_data(image_t * const image, FILE *input, const bool_t color,
+                const int width, const int height, const xelval maxval,
+                const int format) {
+   int row;
+   int i;      /* Cursor into image->pixels arrays */
+   xel * xelrow;
+   /* The following are just the normal rgb -> YCbCr conversion matrix,
+      except normalization to maxval 4095 (12 bit color) is built in
+      */
+   const double coeff_lu_r = +0.2989 / maxval * 4095;
+   const double coeff_lu_g = +0.5866 / maxval * 4095;
+   const double coeff_lu_b = +0.1145 / maxval * 4095;
+   const double coeff_cb_r = -0.1687 / maxval * 4095;
+   const double coeff_cb_g = -0.3312 / maxval * 4095;
+   const double coeff_cb_b = +0.5000 / maxval * 4095;
+   const double coeff_cr_r = +0.5000 / maxval * 4095;
+   const double coeff_cr_g = -0.4183 / maxval * 4095;
+   const double coeff_cr_b = -0.0816 / maxval * 4095;
+
+   xelrow = pnm_allocrow(width);
+
+   i = 0; 
+   for (row = 0; row < height; row++) {
+       int col;
+       pnm_readpnmrow(input, xelrow, width, maxval, format);
+       for (col = 0; col < width; col++) {
+           if (color) {
+               image->pixels[Y][i] = 
+                   coeff_lu_r * PPM_GETR(xelrow[col]) 
+                   + coeff_lu_g * PPM_GETG(xelrow[col])
+                   + coeff_lu_b * PPM_GETB(xelrow[col]) - 2048;
+               image->pixels[Cb][i] = 
+                   coeff_cb_r * PPM_GETR(xelrow[col]) 
+                   + coeff_cb_g * PPM_GETG(xelrow[col])
+                   + coeff_cb_b * PPM_GETB(xelrow[col]);
+               image->pixels[Cr][i] = 
+                   coeff_cr_r * PPM_GETR(xelrow[col]) 
+                   + coeff_cr_g * PPM_GETG(xelrow[col])
+                   + coeff_cr_b * PPM_GETB(xelrow[col]);
+
+               i++;
+           } else 
+               image->pixels[GRAY][i++] =
+                   PNM_GET1(xelrow[col]) * 4095 / maxval - 2048;
+       }
+   }
+
+   free(xelrow);
+}
+
+
+
+image_t *
+read_image (const char *image_name)
+/*
+ *  Read image 'image_name'.
+ *  
+ *  Return value:
+ *	pointer to the image structure.
+ */
+{
+   FILE	    *input;			/* input stream */
+   image_t  *image;			/* pointer to new image structure */
+   int  width, height;		/* image size */
+   xelval   maxval;         /* Maxval of image */
+   int format;              /* Image's format code */
+   bool_t    color;			/* color image ? (YES/NO) */
+
+   if (image_name == NULL)
+       input = stdin;
+   else
+       input = pm_openr((char*)image_name);
+
+   pnm_readpnminit(input, &width, &height, &maxval, &format);
+
+   if (PNM_FORMAT_TYPE(format) == PPM_FORMAT)
+       color = YES;
+   else
+       color = NO;
+
+   if (width < 32)
+       pm_error("Image must have a width of at least 32 pixels.");
+
+   if (height < 32)
+       pm_error("Image must have a height of at least 32 pixels.");
+
+   image = alloc_image (width, height, color, FORMAT_4_4_4);
+
+   read_image_data(image, input, color, width, height, maxval, format);
+
+   pm_close(input);
+   
+   return image;
+}   
+
+void
+write_image (const char *image_name, const image_t *image)
+/*
+ *  Write given 'image' data to the file 'image_name'.
+ *  
+ *  No return value.
+ */
+{
+   FILE	*output;			/* output stream */
+   int format;
+   int row;
+   int i;     /* Cursor into image->pixel arrays */
+   xel * xelrow;
+   unsigned *gray_clip;			/* clipping table */
+
+   assert (image && image_name);
+   
+   if (image->format == FORMAT_4_2_0)
+   {
+      warning ("Writing of images in 4:2:0 format not supported.");
+      return;
+   }
+   
+   if (image_name == NULL)
+       output = stdout;
+   else if (strcmp(image_name, "-") == 0)
+       output = stdout;
+   else
+       output = pm_openw((char*)image_name);
+
+   gray_clip  = init_clipping ();	/* mapping of int -> unsigned */
+   if (!gray_clip)
+      error (fiasco_get_error_message ());
+   init_chroma_tables ();
+
+   format = image->color ? PPM_TYPE : PGM_TYPE;
+   
+   pnm_writepnminit(output, image->width, image->height, 255, format, 0);
+
+   xelrow = pnm_allocrow(image->width);
+   i = 0;
+   for (row = 0; row < image->height; row++) {
+       int col;
+       for (col = 0; col < image->width; col++) {
+           if (image->color) {
+               word_t yval, cbval, crval;
+
+               yval  = image->pixels[Y][i]  / 16 + 128;
+               cbval = image->pixels[Cb][i] / 16;
+               crval = image->pixels[Cr][i] / 16;
+
+               PPM_ASSIGN(xelrow[col], 
+                          gray_clip[yval + Cr_r_tab[crval]],
+                          gray_clip[yval + Cr_g_tab[crval] + Cb_g_tab [cbval]],
+                          gray_clip[yval + Cb_b_tab[cbval]]);
+
+           } else
+               /* The 16 below should be 4095/255 = 16.0588 */
+               PNM_ASSIGN1(xelrow[col], 
+                           gray_clip[image->pixels[GRAY][i]/16+128]);
+           i++;
+       }
+       pnm_writepnmrow(output, xelrow, 
+                       image->width, 255, format, 0);
+   }
+   pnm_freerow(xelrow);
+
+   pm_close(output);
+}
+
+bool_t
+same_image_type (const image_t *img1, const image_t *img2)
+/*
+ *  Check whether the given images 'img1' and `img2' are of the same type.
+ *
+ *  Return value:
+ *	YES	if images 'img1' and `img2' are of the same type
+ *	NO	otherwise.
+ */
+{
+   assert (img1 && img2);
+   
+   return ((img1->width == img2->width)
+	   && (img1->height == img2->height)
+	   && (img1->color == img2->color)
+	   && (img1->format == img2->format));
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+init_chroma_tables (void)
+/*
+ *  Chroma tables are used to perform fast YCbCr->RGB color space conversion.
+ */
+{
+   int crval, cbval, i;
+
+   if (Cr_r_tab != NULL || Cr_g_tab != NULL ||
+       Cb_g_tab != NULL || Cb_b_tab != NULL)
+      return;
+
+   Cr_r_tab = Calloc (768, sizeof (int));
+   Cr_g_tab = Calloc (768, sizeof (int));
+   Cb_g_tab = Calloc (768, sizeof (int));
+   Cb_b_tab = Calloc (768, sizeof (int));
+
+   for (i = 256; i < 512; i++)
+   {
+      cbval = crval  = i - 128 - 256;
+
+      Cr_r_tab[i] =  1.4022 * crval + 0.5;
+      Cr_g_tab[i] = -0.7145 * crval + 0.5;
+      Cb_g_tab[i] = -0.3456 * cbval + 0.5; 
+      Cb_b_tab[i] =  1.7710 * cbval + 0.5;
+   }
+   for (i = 0; i < 256; i++)
+   {
+      Cr_r_tab[i] = Cr_r_tab[256];
+      Cr_g_tab[i] = Cr_g_tab[256];
+      Cb_g_tab[i] = Cb_g_tab[256]; 
+      Cb_b_tab[i] = Cb_b_tab[256];
+   }
+   for (i = 512; i < 768; i++)
+   {
+      Cr_r_tab[i] = Cr_r_tab[511];
+      Cr_g_tab[i] = Cr_g_tab[511];
+      Cb_g_tab[i] = Cb_g_tab[511]; 
+      Cb_b_tab[i] = Cb_b_tab[511];
+   }
+
+   Cr_r_tab += 256 + 128;
+   Cr_g_tab += 256 + 128;
+   Cb_g_tab += 256 + 128;
+   Cb_b_tab += 256 + 128;
+}
+
diff --git a/converter/other/fiasco/lib/image.h b/converter/other/fiasco/lib/image.h
new file mode 100644
index 00000000..958049f6
--- /dev/null
+++ b/converter/other/fiasco/lib/image.h
@@ -0,0 +1,59 @@
+/*
+ *  image.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/10/22 10:43:56 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#ifndef _IMAGE_H
+#define _IMAGE_H
+
+#include <stdio.h>
+#include "types.h"
+#include "fiasco.h"
+
+typedef enum {FORMAT_4_4_4, FORMAT_4_2_0} format_e;
+
+typedef struct image
+/*
+ *  Image data
+ */
+{
+   char      id [7];
+   unsigned  reference_count;
+   unsigned  width;			/* Width of the image */
+   unsigned  height;			/* Height of the image */
+   bool_t    color;			/* Color or grayscale image */
+   format_e  format;			/* Pixel format 4:4:4 or 4:2:0 */
+   word_t   *pixels [3];		/* Pixels in short format */
+} image_t;
+
+image_t *
+cast_image (fiasco_image_t *image);
+image_t *
+alloc_image (unsigned width, unsigned height, bool_t color, format_e format);
+image_t *
+clone_image (image_t *image);
+void
+free_image (image_t *image);
+FILE *
+read_pnmheader (const char *image_name, unsigned *width, unsigned *height,
+		bool_t *color);
+image_t *
+read_image (const char *image_name);
+void
+write_image (const char *image_name, const image_t *image);
+bool_t
+same_image_type (const image_t *img1, const image_t *img2);
+
+#endif /* not _IMAGE_H */
+
diff --git a/converter/other/fiasco/lib/list.c b/converter/other/fiasco/lib/list.c
new file mode 100644
index 00000000..9f516c2e
--- /dev/null
+++ b/converter/other/fiasco/lib/list.c
@@ -0,0 +1,258 @@
+/*
+ *  list.c:		List operations	
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "misc.h"
+#include "list.h"
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+list_t *
+alloc_list (size_t size_of_element)
+/*
+ *  List constructor:
+ *  Allocate a new list.
+ *  Size of list element values is given by 'size_of_element'.
+ *
+ *  Return value:
+ *	pointer to an empty list
+ */
+{
+   list_t *new_list = Calloc (1, sizeof (list_t));
+
+   assert (size_of_element > 0);
+
+   new_list->head 	     = NULL;
+   new_list->tail 	     = NULL;
+   new_list->size_of_element = size_of_element;
+
+   return new_list;
+}
+
+void
+free_list (list_t *list)
+/*
+ *  List destructor:
+ *  Discard list and its elements.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	struct 'list' is discarded
+ */
+{
+   assert (list);
+   
+   while (list_remove (list, HEAD, NULL))
+      ;
+   Free (list);
+}
+
+void
+list_insert (list_t *list, pos_e pos, const void *data)
+/*
+ *  Insert a new 'list' element at head ('pos' = HEAD) or
+ *  tail ('pos' = TAIL) of 'list'. 
+ *  'data' is a pointer to a memory segment of size
+ *  'list'->size_of_element containing the value to store.
+ *  The value is directly copied - no references are stored.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	lists current tail or head is replaced by the new element
+ */
+{
+   node_t *element;
+
+   assert (list && data);
+
+   element 	  = Calloc (1, sizeof (node_t));
+   element->value = Calloc (1, list->size_of_element);
+   memcpy (element->value, data, list->size_of_element);
+
+   if (pos == TAIL)
+   {
+      element->next = NULL;
+      element->prev = list->tail;
+      if (list->tail)
+	 list->tail->next = element;
+      list->tail = element;
+      if (!list->head)
+	 list->head = element;
+   }
+   else					/* pos == HEAD */
+   {
+      element->prev = NULL;
+      element->next = list->head;
+      if (list->head)
+	 list->head->prev = element;
+      list->head = element;
+      if (!list->tail)
+	 list->tail = element;
+   }
+}
+
+bool_t
+list_remove (list_t *list, pos_e pos, void *data)
+/*
+ *  Remove 'list' element from head or tail of 'list'.
+ *
+ *  Return value:
+ *	TRUE on success,
+ *	FALSE if list is empty or
+ *	      if list value data is NULL
+ *
+ *  Side effects:
+ *	lists current head or tail is removed
+ *	value of the removed list element (if not NULL) is copied to
+ *      'data' (if 'data' is not NULL)
+ */
+{
+   node_t *element;
+   void	  *valueptr;
+
+   assert (list);
+   
+   if (pos == TAIL)
+   {
+      element = list->tail;
+      if (element)
+      {
+	 list->tail = element->prev;
+	 valueptr   = element->value;
+	 Free (element);
+      }
+      else
+	 valueptr = NULL;
+      if (!list->tail)			/* 'element' was last node */
+	 list->head = NULL;
+   }
+   else					/* pos == HEAD */
+   {
+      element = list->head;
+      if (element)
+      {
+	 list->head = element->next;
+	 valueptr   = element->value;
+	 Free (element);
+      }
+      else
+	 valueptr = NULL;
+      if (!list->head)			/* 'element' was last node */
+	 list->tail = NULL;
+   }
+
+   if (valueptr)			/* copy value of node */
+   {
+      if (data)				
+	 memcpy (data, valueptr, list->size_of_element);
+      Free (valueptr);
+   }
+   
+   return valueptr ? TRUE : FALSE;
+}
+
+bool_t
+list_element_n (const list_t *list, pos_e pos, unsigned n, void *data)
+/*
+ *  Get value of 'list' element number 'n'.
+ *  (First element is list head if 'pos' == HEAD
+ *                 or list tail if 'pos' == TAIL.
+ *   Accordingly, traverse the list in ascending or descending order).
+ *  
+ *  Return value:
+ *	TRUE on success, FALSE if there is no element 'n'
+ *
+ *  Side effects:
+ *	value of list element 'n' is copied to 'data' 
+ */
+{
+   node_t *element;
+
+   assert (list && data);
+   
+   if (pos == HEAD)
+      for (element = list->head; element != NULL && n;
+	   element = element->next, n--)
+	 ;
+   else
+      for (element = list->tail; element != NULL && n;
+	   element = element->prev, n--)
+	 ;
+      
+   if (element)
+   {
+      memcpy (data, element->value, list->size_of_element);
+      return TRUE;
+   }
+   else
+      return FALSE;
+}
+
+unsigned
+list_sizeof (const list_t *list)
+/*
+ *  Count number of 'list' elements.
+ *
+ *  Return value:
+ *	number of 'list' elements.
+ */
+{
+   node_t   *element;
+   unsigned  n = 0;
+
+   assert (list);
+   
+   for (element = list->head; element != NULL; element = element->next)
+      n++;
+
+   return n;
+}
+
+void
+list_foreach (const list_t *list, void (*function)(void *, void *), void *data)
+/*
+ *  Call 'function' for each element of the 'list'.
+ *  Parameters given to 'function' are a pointer to the value of the
+ *  current 'list' element and the user pointer 'data'.
+ *
+ *  No return value.
+ */
+{
+   node_t *element;
+
+   assert (list && function && data);
+   
+   for (element = list->head; element; element = element->next)
+      function (element->value, data);
+}
+
diff --git a/converter/other/fiasco/lib/list.h b/converter/other/fiasco/lib/list.h
new file mode 100644
index 00000000..db7c08b2
--- /dev/null
+++ b/converter/other/fiasco/lib/list.h
@@ -0,0 +1,72 @@
+/*
+ *  list.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _LIST_H
+#define _LIST_H
+
+#include <stdio.h>
+#include <stddef.h>
+
+typedef struct node
+{
+   struct node *prev;			/* pointer to prev list element */
+   struct node *next;			/* pointer to next list element */
+   void	       *value;			/* pointer to value of node */
+} node_t;
+
+typedef struct list
+{
+   node_t *head;
+   node_t *tail;
+   size_t  size_of_element;		/* number of bytes to store value */
+} list_t;
+
+typedef enum {TAIL, HEAD} pos_e;
+
+/*
+ *  Alias definitions for queue and stack
+ */
+
+typedef list_t lqueue_t ;
+#define alloc_queue		alloc_list
+#define free_queue		free_list		
+#define queue_append(q, d)	(list_insert ((q), TAIL, (d)))
+#define queue_remove(q, d)	(list_remove ((q), HEAD, (d)))
+
+typedef list_t lstack_t ;
+#define alloc_stack		alloc_list
+#define free_stack		free_list
+#define stack_push(q, d)	(list_insert ((q), TAIL, (d)))
+#define stack_pop(q, d)		(list_remove ((q), TAIL, (d)))
+
+list_t *
+alloc_list (size_t size_of_element);
+void 
+free_list (list_t *list);
+bool_t
+list_element_n (const list_t *list, pos_e pos, unsigned n, void *data);
+void
+list_foreach (const list_t *list, void (*function)(void *, void *),
+	      void *data);
+void
+list_insert (list_t *list, pos_e pos, const void *data);
+bool_t
+list_remove (list_t *list, pos_e pos, void *data);
+unsigned
+list_sizeof (const list_t *list);
+
+#endif /* not _LIST_H */
+
diff --git a/converter/other/fiasco/lib/macros.h b/converter/other/fiasco/lib/macros.h
new file mode 100644
index 00000000..877abeea
--- /dev/null
+++ b/converter/other/fiasco/lib/macros.h
@@ -0,0 +1,70 @@
+/*
+ *  macros.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MACROS_H
+#define _MACROS_H
+
+#include <string.h>
+/*******************************************************************************
+
+			  System configuration section
+  
+*******************************************************************************/
+
+#ifndef SEEK_CUR
+#   define SEEK_CUR	1
+#endif /* not SEEK_CUR */
+
+#ifdef WIN32
+#undef max
+#undef min
+#endif /* not WIN32 */
+
+/*****************************************************************************
+
+				Various macros
+  
+*****************************************************************************/
+
+#define streq(str1, str2)	(strcmp ((str1), (str2)) == 0)
+#define strneq(str1, str2)	(strcmp ((str1), (str2)) != 0)
+#define square(x)		((x) * (x))
+#define first_band(color)	((unsigned) ((color) ? Y  : GRAY))
+#define last_band(color)        ((unsigned) ((color) ? Cr : GRAY))
+#define width_of_level(l)	((unsigned) (1 << ((l) >> 1)))
+#define height_of_level(l)	((unsigned) (1 << (((l) + 1) >> 1)))
+#define size_of_level(l)	((unsigned) (1 << (l)))
+#define address_of_level(l)	((unsigned) (size_of_level (l) - 1))
+#define size_of_tree(l)		((unsigned) (address_of_level ((l) + 1)))
+#define is_odd(n)		(abs (n) % 2)
+#ifndef max
+#define max(a,b)		((a) < (b) ? (b) : (a))
+#endif
+#ifndef min
+#define min(a,b)	        ((a) > (b) ? (b) : (a))
+#endif
+#define _(x) (x) 
+
+
+#define	MAXSTRLEN 1024
+#define	MAXSTRLEN_SCANF "%1024s"
+
+typedef enum color {GRAY = 0, Y = 0, Cb = 1, Cr = 2} color_e;
+
+#endif /* _MACROS_H */
+
+
+
diff --git a/converter/other/fiasco/lib/misc.c b/converter/other/fiasco/lib/misc.c
new file mode 100644
index 00000000..02a1314f
--- /dev/null
+++ b/converter/other/fiasco/lib/misc.c
@@ -0,0 +1,563 @@
+/*
+ *  misc.c:		Some usefull functions, that don't fit in one of 
+ *			the other files and that are needed by at least
+ *			two modules. 
+ *
+ *  Written by:		Stefan Frank
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <ctype.h>
+
+#ifdef TIME_WITH_SYS_TIME
+#	include <sys/time.h>
+#	include <time.h>
+#else  /* not TIME_WITH_SYS_TIME */
+#	if HAVE_SYS_TIME_H
+#		include <sys/time.h>
+#	else /* not HAVE_SYS_TIME_H */
+#		include <time.h>
+#	endif /* not HAVE_SYS_TIME_H */
+#endif /* not TIME_WITH_SYS_TIME */
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#if HAVE_STRING_H
+#	include <string.h>
+#else /* not HAVE_STRING_H */
+#	include <strings.h>
+#endif /* not HAVE_STRING_H */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "bit-io.h"
+#include "misc.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+remove_comments (FILE *file);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void *
+Calloc (size_t n, size_t size)
+/*
+ *  Allocate memory like calloc ().
+ *
+ *  Return value: Pointer to the new block of memory on success,
+ *		  otherwise the program is terminated.
+ */
+{
+   void	*ptr;				/* pointer to the new memory block */
+
+   if (n <= 0 || size <= 0)
+      error ("Can't allocate memory for %d items of size %d",
+	     (int) n, (int) size);
+
+   ptr = calloc (n, size);
+   if (!ptr)
+      error ("Out of memory!");
+
+   return ptr;
+}
+
+void
+Free (void *memory)
+/*
+ *  Free memory given by the pointer 'memory'
+ *
+ *  No return value.
+ */
+{
+   if (memory != NULL)
+      free (memory);
+   else
+      warning ("Can't free memory block <NULL>.");
+}
+
+unsigned
+prg_timer (clock_t *last_timer, enum action_e action)
+/*
+ *  If 'action' == START then store current value of system timer.
+ *  If 'action' == STOP	 then compute number of elapsed micro seconds since
+ *			 the last time 'prg_timer' was called
+ *			 with 'action' == START.
+ *
+ *  Return value:
+ *	Number of elapsed micro seconds if 'action' == STOP
+ *	0				if 'action' == START
+ *
+ *  Side effects:
+ *	last_timer is set to current timer if action == START
+ */
+{
+   assert (last_timer);
+   
+   if (action == START)
+   {
+      *last_timer = clock ();
+      return 0;
+   }
+   else
+      return (clock () - *last_timer) / (CLOCKS_PER_SEC / 1000.0);
+}
+
+real_t 
+read_real (FILE *infile)
+/* 
+ *  Read one real value from the given input stream 'infile'.
+ *  
+ *  Return value:
+ *	real value on success
+ */
+{
+   float input;
+
+   assert (infile);
+   
+   remove_comments (infile);
+   if (fscanf(infile, "%f", &input) != 1)
+      error("Can't read float value!");
+
+   return (real_t) input;
+}
+
+int 
+read_int (FILE *infile)
+/* 
+ *  Read one integer value from the given input stream 'infile'.
+ *
+ *  Return value:
+ *	integer value on success
+ */
+{
+   int input;				/* integer */
+
+   assert (infile);
+   
+   remove_comments (infile);
+   if (fscanf(infile, "%d", &input) != 1)
+      error("Can't read integer value!");
+
+   return input;
+}
+   
+static void
+remove_comments (FILE *file)
+/*
+ *  Remove shell/pgm style comments (#) from the input 'file'
+ *
+ *  No return value.
+ */
+{
+   int c;				/* current character */
+   
+   assert (file);
+   
+   do
+   {
+      while (isspace(c = getc (file)))
+	 ;
+      if (c == EOF)
+	 error ("EOF reached, input seems to be truncated!");
+      if (c == '#')
+      {
+	 int dummy;
+	 
+	 while (((dummy = getc (file)) != '\n') && dummy != EOF)
+	    ;
+	 if (dummy == EOF)
+	    error ("EOF reached, input seems to be truncated!");
+      }
+      else 
+	 ungetc (c, file);
+   } while (c == '#');
+}
+
+void
+write_rice_code (unsigned value, unsigned rice_k, bitfile_t *output)
+/*
+ *  Write 'value' to the stream 'output' using Rice coding with base 'rice_k'.
+ *
+ *  No return value.
+ */
+{
+   unsigned unary;			/* unary part of Rice Code */
+
+   assert (output);
+   
+   for (unary = value >> rice_k; unary; unary--)
+      put_bit (output, 1);
+   put_bit (output, 0);
+   put_bits (output, value & ((1 << rice_k) - 1), rice_k);
+}
+
+unsigned
+read_rice_code (unsigned rice_k, bitfile_t *input)
+/*
+ *  Read a Rice encoded integer (base 'rice_k') from the stream 'input'.
+ *
+ *  Return value:
+ *	decoded integer
+ */
+{
+   unsigned unary;			/* unary part of Rice code */
+   
+   assert (input);
+   
+   for (unary = 0; get_bit (input); unary++) /* unary part */
+      ;
+
+   return (unary << rice_k) | get_bits (input, rice_k);
+}
+
+void
+write_bin_code (unsigned value, unsigned maxval, bitfile_t *output)
+/*
+ *  Write 'value' to the stream 'output' using an adjusted binary code
+ *  based on given 'maxval'.
+ *
+ *  No return value.
+ */
+{
+   unsigned k;
+   unsigned r;
+   
+   assert (output && maxval && value <= maxval);
+
+   k = log2 (maxval + 1);
+   r = (maxval + 1) % (1 << k);
+
+   if (value < maxval + 1 - 2 * r)	/* 0, ... , maxval - 2r */
+      put_bits (output, value, k);
+   else					/* maxval - 2r + 1, ..., maxval */
+      put_bits (output, value + maxval + 1 - 2 * r, k + 1);
+}
+
+unsigned
+read_bin_code (unsigned maxval, bitfile_t *input)
+/*
+ *  Read a bincode encoded integer from the stream 'input'.
+ *
+ *  Return value:
+ *	decoded integer
+ */
+{
+   unsigned k;
+   unsigned r;
+   unsigned value;
+   
+   assert (input);
+
+   k = log2 (maxval + 1);
+   r = (maxval + 1) % (1 << k);
+
+   value = get_bits (input, k);
+   if (value < maxval + 1 - 2 * r)
+      return value;
+   else
+   {
+      value <<= 1;
+      if (get_bit (input))
+	 value++;
+      return value - maxval - 1 + 2 * r;
+   }
+}
+
+unsigned
+bits_rice_code (unsigned value, unsigned rice_k)
+/*
+ *  Compute number of bits needed for coding integer 'value'
+ *  with given Rice code 'rice_k'.
+ *
+ *  Return value:
+ *	number of bits
+ */
+{
+   unsigned unary;
+   unsigned bits = 0;
+   
+   for (unary = value >> rice_k; unary; unary--)
+      bits++;
+   bits += rice_k + 1;
+
+   return bits;
+}
+
+unsigned
+bits_bin_code (unsigned value, unsigned maxval)
+/*
+ *  Compute number of bits needed for coding integer 'value'
+ *  with adjusted binary code of given maximum value 'maxval'.
+ *
+ *  Return value:
+ *	number of bits
+ */
+{
+   unsigned k;
+   unsigned r;
+
+   assert (maxval && value <= maxval);
+
+   k = log2 (maxval + 1);
+   r = (maxval + 1) % (1 << k);
+
+   return value < maxval + 1 - 2 * r ? k : k + 1;
+}
+
+unsigned *
+init_clipping (void)
+/*
+ *  Initialize the clipping tables
+ *
+ *  Return value:
+ *	pointer to clipping table
+ */
+{
+   static unsigned *gray_clip = NULL;	/* clipping array */
+
+   if (gray_clip == NULL)		/* initialize clipping table */
+   {
+      int i;				/* counter */
+
+      gray_clip  = calloc (256 * 3, sizeof (unsigned));
+      if (!gray_clip)
+      {
+	 set_error (_("Out of memory."));
+	 return NULL;
+      }
+      gray_clip += 256;
+
+      for (i = -256; i < 512; i++)
+	 if (i < 0)
+	    gray_clip [i] = 0;
+	 else if (i > 255)
+	    gray_clip [i] = 255;
+	 else
+	    gray_clip [i] = i;
+   }
+
+   return gray_clip;
+}
+
+#ifndef HAVE_MEMMOVE
+void *
+memmove (void *v_dst, const void *v_src, size_t n)
+/*
+ *  Copy 'n' bytes from memory area 'src' to memory area 'dest'.
+ *  The memory areas may overlap.
+ *
+ *  Return value:
+ *	pointer 'dest'
+ */
+{
+   byte_t	*to, *dst = (byte_t *) v_dst;
+   const byte_t	*from, *src = (byte_t *) v_src;
+   
+   assert (v_dst && v_src);
+   
+   if (dst <= src)
+   {
+      from = src;
+      to   = dst;
+      for (; n; n--)
+	 *to++ = *from++;
+   }
+   else
+   { 
+      from = src + (n - 1);
+      to   = dst + (n - 1);
+      for (; n; n--)
+	 *to-- = *from--;
+   }
+   
+   return v_dst;
+}
+#endif /* not HAVE_MEMMOVE */
+
+#ifndef HAVE_STRDUP
+char *
+strdup (const char *s)
+/*
+ *  Duplicate given string 's'.
+ *
+ *  Return value:
+ *	pointer to new string value
+ */
+{
+   assert (s);
+   
+   return strcpy (Calloc (strlen (s) + 1, sizeof (char)), s);
+}
+#endif /* not HAVE_STRDUP */
+
+/* Note that some systems have a "log2()" in the math library and some
+   have a "log2" macro.  So we name ours Log2.  But to avoid lots of
+   differences from the original fiasco source code, we define a
+   macro log2 in config.h to expand to Log2.
+   */
+double
+Log2 (double x)
+/*
+ *  Return value:
+ *	base-2 logarithm of 'x'
+ */
+{
+   return log (x) / 0.69314718;
+}
+
+#ifndef HAVE_STRCASECMP
+bool_t
+strcaseeq (const char *s1, const char *s2)
+/*
+ *  Compare strings 's1' and 's2', ignoring  the  case of the characters.
+ *
+ *  Return value:
+ *	TRUE if strings match, else FALSE
+ */
+{
+   bool_t  matched;
+   char	  *ls1, *ls2, *ptr;
+
+   assert (s1 && s2);
+   
+   ls1 = strdup (s1);
+   ls2 = strdup (s2);
+   
+   for (ptr = ls1; *ptr; ptr++)
+      *ptr = tolower (*ptr);
+   for (ptr = ls2; *ptr; ptr++)
+      *ptr = tolower (*ptr);
+
+   matched = streq (ls1, ls2) ? YES : NO;
+
+   Free (ls1);
+   Free (ls2);
+   
+   return matched;
+}
+#endif /* not HAVE_STRCASECMP */
+
+real_t
+variance (const word_t *pixels, unsigned x0, unsigned y0,
+	  unsigned width, unsigned height, unsigned cols)
+/*
+ *  Compute variance of subimage ('x0', y0', 'width', 'height') of 
+ *  the image data given by 'pixels' ('cols' is the number of pixels
+ *  in one row of the image).
+ *
+ *  Return value:
+ *	variance
+ */
+{
+   real_t   average;			/* average of pixel values */
+   real_t   variance;			/* variance of pixel values */
+   unsigned x, y;			/* pixel counter */
+   unsigned n;				/* number of pixels */
+
+   assert (pixels);
+   
+   for (average = 0, n = 0, y = y0; y < y0 + height; y++)
+      for (x = x0; x < min (x0 + width, cols); x++, n++)
+	 average += pixels [y * cols + x] / 16;
+
+   average /= n;
+
+   for (variance = 0, y = y0; y < y0 + height; y++)
+      for (x = x0; x < min (x0 + width, cols); x++)
+	 variance += square ((pixels [y * cols + x] / 16) - average);
+
+   return variance;
+}
+
+int
+sort_asc_word (const void *value1, const void *value2)
+/*
+ *  Sorting function for quicksort.
+ *  Smallest values come first.
+ */
+{
+   if (* (word_t *) value1 < * (word_t *) value2)
+      return -1;
+   else if (* (word_t *) value1 > * (word_t *) value2)
+      return +1;
+   else
+      return 0;
+}
+
+int
+sort_desc_word (const void *value1, const void *value2)
+/*
+ *  Sorting function for quicksort.
+ *  Largest values come first.
+ */
+{
+   if (* (word_t *) value1 > * (word_t *) value2)
+      return -1;
+   else if (* (word_t *) value1 < * (word_t *) value2)
+      return +1;
+   else
+      return 0;
+}
+
+int
+sort_asc_pair (const void *value1, const void *value2)
+/*
+ *  Sorting function for quicksort.
+ *  Smallest values come first.
+ */
+{
+   word_t v1 = ((pair_t *) value1)->key;
+   word_t v2 = ((pair_t *) value2)->key;
+   
+   if (v1 < v2)
+      return -1;
+   else if (v1 > v2)
+      return +1;
+   else
+      return 0;
+}
+
+int
+sort_desc_pair (const void *value1, const void *value2)
+/*
+ *  Sorting function for quicksort.
+ *  Largest values come first.
+ */
+{
+   word_t v1 = ((pair_t *) value1)->key;
+   word_t v2 = ((pair_t *) value2)->key;
+
+   if (v1 > v2)
+      return -1;
+   else if (v1 < v2)
+      return +1;
+   else
+      return 0;
+}
diff --git a/converter/other/fiasco/lib/misc.h b/converter/other/fiasco/lib/misc.h
new file mode 100644
index 00000000..29456590
--- /dev/null
+++ b/converter/other/fiasco/lib/misc.h
@@ -0,0 +1,98 @@
+/*
+ *  misc.h
+ *
+ *  Written by:		Stefan Frank
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MISC_H
+#define _MISC_H
+
+#include "config.h"
+
+#if TIME_WITH_SYS_TIME
+#	include <sys/time.h>
+#	include <time.h>
+#else  /* not TIME_WITH_SYS_TIME */
+#	if HAVE_SYS_TIME_H
+#		include <sys/time.h>
+#	else /* not HAVE_SYS_TIME_H */
+#		include <time.h>
+#	endif /* not HAVE_SYS_TIME_H */
+#endif /* not TIME_WITH_SYS_TIME */
+
+#include <stdio.h>
+#include "types.h"
+#include "bit-io.h"
+
+enum action_e {START, STOP};
+
+void *
+Calloc (size_t n, size_t size);
+void
+Free (void *memory);
+unsigned
+prg_timer (clock_t *ptimer, enum action_e action);
+int 
+read_int(FILE *infile);
+real_t 
+read_real(FILE *infile);
+unsigned
+read_rice_code (unsigned rice_k, bitfile_t *input);
+void
+write_rice_code (unsigned value, unsigned rice_k, bitfile_t *output);
+void
+write_bin_code (unsigned value, unsigned maxval, bitfile_t *output);
+unsigned
+bits_bin_code (unsigned value, unsigned maxval);
+unsigned
+bits_rice_code (unsigned value, unsigned rice_k);
+unsigned
+read_bin_code (unsigned maxval, bitfile_t *input);
+unsigned *
+init_clipping (void);
+real_t
+variance (const word_t *pixels, unsigned x0, unsigned y0,
+	  unsigned width, unsigned height, unsigned cols);
+
+#ifndef HAVE_MEMMOVE
+void *
+memmove(void *dest, const void *src, size_t n);
+#endif /* not HAVE_MEMMOVE */
+
+double
+Log2 (double x);
+#ifndef HAVE_STRDUP
+char *
+strdup (const char *s);
+#endif
+#ifndef HAVE_STRCASECMP
+bool_t
+strcaseeq (const char *s1, const char *s2);
+#else  /* HAVE_STRCASECMP */
+int
+strcasecmp (const char *s1, const char *s2);
+#define strcaseeq(s1, s2) (strcasecmp ((s1), (s2)) == 0)
+#endif /* HAVE_STRCASECMP */
+
+int
+sort_asc_word (const void *value1, const void *value2);
+int
+sort_desc_word (const void *value1, const void *value2);
+int
+sort_asc_pair (const void *value1, const void *value2);
+int
+sort_desc_pair (const void *value1, const void *value2);
+
+#endif /* not _MISC_H */
+
diff --git a/converter/other/fiasco/lib/mvcode.c b/converter/other/fiasco/lib/mvcode.c
new file mode 100644
index 00000000..d9ce91e2
--- /dev/null
+++ b/converter/other/fiasco/lib/mvcode.c
@@ -0,0 +1,14 @@
+#include "mvcode.h"
+
+unsigned mv_code_table [33][2] =
+/*
+ *  MPEG's huffman code for vector components. Format: code_value, length
+ */
+{
+   {0x19, 11}, {0x1b, 11}, {0x1d, 11}, {0x1f, 11}, {0x21, 11}, {0x23, 11},
+   {0x13, 10}, {0x15, 10}, {0x17, 10}, {0x7, 8}, {0x9, 8}, {0xb, 8}, {0x7, 7},
+   {0x3, 5}, {0x3, 4}, {0x3, 3}, {0x1, 1}, {0x2, 3}, {0x2, 4}, {0x2, 5},
+   {0x6, 7}, {0xa, 8}, {0x8, 8}, {0x6, 8}, {0x16, 10}, {0x14, 10}, {0x12, 10}, 
+   {0x22, 11}, {0x20, 11}, {0x1e, 11}, {0x1c, 11}, {0x1a, 11}, {0x18, 11}
+};
+
diff --git a/converter/other/fiasco/lib/mvcode.h b/converter/other/fiasco/lib/mvcode.h
new file mode 100644
index 00000000..f43f2081
--- /dev/null
+++ b/converter/other/fiasco/lib/mvcode.h
@@ -0,0 +1,6 @@
+#ifndef MVCODE_H_INCLUDED
+#define MVCODE_H_INCLUDED
+
+extern unsigned mv_code_table [33][2];
+
+#endif
diff --git a/converter/other/fiasco/lib/rpf.c b/converter/other/fiasco/lib/rpf.c
new file mode 100644
index 00000000..ac7d48ca
--- /dev/null
+++ b/converter/other/fiasco/lib/rpf.c
@@ -0,0 +1,223 @@
+/*
+ *  rpf.c:		Conversion of float to reduced precision format values
+ *
+ *  Written by:		Stefan Frank
+ *			Richard Krampfl
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "misc.h"
+#include "rpf.h"
+
+/* 
+ * CAUTION: The IEEE float format must be used by your compiler,
+ *          or all following code is void!
+ */
+
+#ifdef WORDS_BIGENDIAN
+/*
+ *  Big-Endian Architecture (e.g. SUN, Motorola)
+ *  Memory representation of integer 0x00112233 is 00,11,22,33
+ */
+
+enum real_bytes {BYTE_0, BYTE_1, BYTE_2, BYTE_3};
+
+#else  /* not WORDS_BIGENDIAN */
+/*
+ *  Little-Endian Architecture (e.g. Intel, VAX, Alpha)
+ *  Memory representation of integer 0x00112233 is 33,22,11,00
+ */
+
+enum real_bytes {BYTE_3, BYTE_2, BYTE_1, BYTE_0};
+
+#endif /* not WORDS_BIGENDIAN */
+
+const int RPF_ZERO = -1;
+
+/*****************************************************************************
+
+			       private code
+  
+*****************************************************************************/
+
+int
+rtob (real_t f, const rpf_t *rpf)
+/*
+ *  Convert real number 'f' into fixed point format.
+ *  The real number in [-'range'; +'range'] is scaled to [-1 ; +1].
+ *  Sign and the first 'precision' - 1 bits of the mantissa are
+ *  packed into one integer.  
+ *
+ *  Return value:
+ *	real value in reduced precision format
+ */
+{  
+   unsigned int	mantissa;
+   int		exponent, sign;
+   union
+   {
+      float f;
+      unsigned char c[4];
+   } v;					/* conversion dummy */
+
+   f  /= rpf->range;			/* scale f to [-1,+1] */	
+   v.f = f;
+
+   /*
+    *  Extract mantissa (23 Bits), exponent (8 Bits) and sign (1 Bit)
+    */
+
+   mantissa = ((((v.c[BYTE_1] & 127) << 8 ) | v.c[BYTE_2]) << 8) | v.c[BYTE_3];
+   exponent = (((v.c[BYTE_0] & 127) << 1) | (v.c[BYTE_1] & 128 ? 1 : 0)) - 126;
+   sign     = v.c[BYTE_0] & 128 ? 1 : 0;
+		
+   /*
+    *  Generate reduced precision mantissa.
+    */
+   mantissa >>= 1;				/* shift 1 into from left */
+   mantissa  |= (1 << 22);
+   if (exponent > 0) 
+      mantissa <<= exponent;
+   else
+      mantissa >>= -exponent;  
+   
+   mantissa >>= (23 - rpf->mantissa_bits - 1);
+
+   mantissa +=  1;			/* Round last bit. */
+   mantissa >>= 1;
+   
+   if (mantissa == 0)			/* close to zero */
+      return RPF_ZERO;
+   else if (mantissa >= (1U << rpf->mantissa_bits)) /* overflow */
+      return sign;
+   else
+      return ((mantissa & ((1U << rpf->mantissa_bits) - 1)) << 1) | sign;
+}
+
+float
+btor (int binary, const rpf_t *rpf)
+/*
+ *  Convert value 'binary' in reduced precision format to a real value.
+ *  For more information refer to function lin_rtob() above.
+ *
+ *  Return value:
+ *	converted value
+ */
+{
+   unsigned int	mantissa;
+   int		sign, exponent;
+   union
+   {
+      float f;
+      unsigned char c[4];
+   } value;
+
+   if (binary == RPF_ZERO)
+      return 0;
+
+   if (binary < 0 || binary >= 1 << (rpf->mantissa_bits + 1))
+      error ("Reduced precision format: value %d out of range.", binary);
+
+   /*
+    *  Restore IEEE float format:
+    *  mantissa (23 Bits), exponent (8 Bits) and sign (1 Bit)
+    */
+   
+   sign       = binary & 1;
+   mantissa   = (binary & ((1 << (rpf->mantissa_bits + 1)) - 1)) >> 1; 
+   mantissa <<= (23 - rpf->mantissa_bits);
+   exponent   = 0;
+
+   if (mantissa == 0)
+   {
+      value.f = (sign ? -1.0 : 1.0);
+   }
+   else
+   {
+      while (!(mantissa & (1 << 22)))	/* normalize mantissa */
+      {
+	 exponent--;
+	 mantissa <<= 1;
+      }
+      mantissa <<= 1;
+
+      value.c[BYTE_0] = (sign << 7) | ((exponent + 126) >> 1);
+      value.c[BYTE_1] = (((exponent + 126) & 1) << 7)
+			| ((mantissa  >> 16) & 127);
+      value.c[BYTE_2] = (mantissa >> 8) & 255;
+      value.c[BYTE_3] = mantissa & 255;
+   }
+   
+   return value.f * rpf->range;		/* expand [ -1 ; +1 ] to
+					   [ -range ; +range ] */
+}
+
+rpf_t *
+alloc_rpf (unsigned mantissa, fiasco_rpf_range_e range)
+/*
+ *  Reduced precision format constructor.
+ *  Allocate memory for the rpf_t structure.
+ *  Number of mantissa bits is given by `mantissa'.
+ *  The range of the real values is in the interval [-`range', +`range'].
+ *  In case of invalid parameters, a structure with default values is
+ *  returned. 
+ *
+ *  Return value
+ *	pointer to the new rpf structure
+ */
+{
+   rpf_t *rpf = Calloc (1, sizeof (rpf_t));
+   
+   if (mantissa < 2)
+   {
+      warning (_("Size of RPF mantissa has to be in the interval [2,8]. "
+		 "Using minimum value 2.\n"));
+      mantissa = 2;
+   }
+   else if (mantissa > 8)
+   {
+      warning (_("Size of RPF mantissa has to be in the interval [2,8]. "
+		 "Using maximum value 8.\n"));
+      mantissa = 2;
+   }
+
+   rpf->mantissa_bits = mantissa;
+   rpf->range_e       = range;
+   switch (range)
+   {
+      case FIASCO_RPF_RANGE_0_75:
+	 rpf->range = 0.75;
+	 break;
+      case FIASCO_RPF_RANGE_1_50:
+	 rpf->range = 1.50;
+	 break;
+      case FIASCO_RPF_RANGE_2_00:
+	 rpf->range = 2.00;
+	 break;
+      case FIASCO_RPF_RANGE_1_00:
+	 rpf->range = 1.00;
+	 break;
+      default:
+	 warning (_("Invalid RPF range specified. Using default value 1.0."));
+	 rpf->range   = 1.00;
+	 rpf->range_e = FIASCO_RPF_RANGE_1_00;
+	 break;
+   }
+   return rpf;
+}
diff --git a/converter/other/fiasco/lib/rpf.h b/converter/other/fiasco/lib/rpf.h
new file mode 100644
index 00000000..ba3ff6be
--- /dev/null
+++ b/converter/other/fiasco/lib/rpf.h
@@ -0,0 +1,47 @@
+/*
+ *  rpf.h
+ *
+ *  Written by:		Stefan Frank
+ *			Richard Krampfl
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _RPF_H
+#define _RPF_H
+
+#include "types.h"
+#include "fiasco.h"
+
+typedef struct rpf
+{
+   unsigned    	      mantissa_bits;	/* number of bits used for mantissa */
+   real_t      	      range;		/* scale value to [-range, +range] */
+   fiasco_rpf_range_e range_e;
+} rpf_t;
+
+int
+rtob (real_t real, const rpf_t *rpf);
+real_t 
+btor (int b, const rpf_t *rpf);
+rpf_t *
+alloc_rpf (unsigned mantissa, fiasco_rpf_range_e range);
+
+extern const int RPF_ZERO;
+
+#endif /* not _RPF_H */
+
+
+
+
+
+
diff --git a/converter/other/fiasco/lib/types.h b/converter/other/fiasco/lib/types.h
new file mode 100644
index 00000000..16d8028c
--- /dev/null
+++ b/converter/other/fiasco/lib/types.h
@@ -0,0 +1,38 @@
+/*
+ *  types.h
+ *
+ *  Written by:     Ullrich Hafner
+ *      
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:49:37 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _FIASCO_TYPES_H
+#define _FIASCO_TYPES_H
+
+#undef FALSE
+#undef NO
+#undef TRUE
+#undef YES
+
+enum fiasco_boolean { NO = 0, FALSE = 0, YES = 1, TRUE = 1};
+
+typedef float                real_t;
+typedef enum fiasco_boolean  bool_t;
+typedef unsigned char        byte_t;
+typedef short                word_t;
+typedef unsigned short       u_word_t;
+typedef struct pair
+{
+   word_t key;
+   word_t value;
+} pair_t;
+
+#endif
diff --git a/converter/other/fiasco/output/Makefile b/converter/other/fiasco/output/Makefile
new file mode 100644
index 00000000..3bdc4635
--- /dev/null
+++ b/converter/other/fiasco/output/Makefile
@@ -0,0 +1,26 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/../../../..
+  BUILDDIR = $(SRCDIR)
+endif
+FIASCOSUBDIR = converter/other/fiasco
+SUBDIR = $(FIASCOSUBDIR)/output
+VPATH=.:$(SRCDIR)/$(SUBDIR)
+
+include $(BUILDDIR)/Makefile.config
+
+OBJECTS =  matrices.o mc.o nd.o tree.o weights.o write.o
+
+MERGE_OBJECTS = $(OBJECTS)
+
+INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR) \
+	   -I$(SRCDIR)/$(FIASCOSUBDIR)/lib \
+	   -I$(SRCDIR)/$(FIASCOSUBDIR)/codec 
+
+all: libfiasco_output.a
+
+include $(SRCDIR)/Makefile.common
+
+libfiasco_output.a: $(OBJECTS)
+	$(AR) -rc $@ $(OBJECTS)
+	$(RANLIB) $@
+
diff --git a/converter/other/fiasco/output/matrices.c b/converter/other/fiasco/output/matrices.c
new file mode 100644
index 00000000..fd8d31e2
--- /dev/null
+++ b/converter/other/fiasco/output/matrices.c
@@ -0,0 +1,547 @@
+/*
+ *  matrices.c:		Output of transitions matrices
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/* NETPBM: When you call delta_encoding() with last_domain < 4, it
+   crashes.  And we have seen it happen.
+*/
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#endif /* not STDC_HEADERS */
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "bit-io.h"
+#include "arith.h"
+#include "misc.h"
+#include "wfalib.h"
+
+#include "matrices.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static unsigned
+delta_encoding (bool_t use_normal_domains, bool_t use_delta_domains,
+		const wfa_t *wfa, unsigned last_domain, bitfile_t *output);
+static unsigned
+column_0_encoding (const wfa_t *wfa, unsigned last_row, bitfile_t *output);
+static unsigned
+chroma_encoding (const wfa_t *wfa, bitfile_t *output);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+unsigned
+write_matrices (bool_t use_normal_domains, bool_t use_delta_domains,
+		const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write transition matrices of 'wfa' to stream 'output'.
+ *
+ *  Return value:
+ *	number of transitions encoded
+ */
+{
+   unsigned root_state;			/* root of luminance */
+   unsigned total = 0;			/* number of transitions */
+   
+   root_state = wfa->wfainfo->color
+		? wfa->tree [wfa->tree [wfa->root_state][0]][0]
+		: wfa->root_state;
+   
+   total  = column_0_encoding (wfa, root_state, output);
+
+   total += delta_encoding (use_normal_domains, use_delta_domains,
+			    wfa, root_state, output);
+   
+   if (wfa->wfainfo->color)
+      total += chroma_encoding (wfa, output);
+   
+   return total;
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static unsigned
+delta_encoding (bool_t use_normal_domains, bool_t use_delta_domains,
+		const wfa_t *wfa, unsigned last_domain, bitfile_t *output)
+/*
+ *  Write transition matrices with delta coding to stream 'input'.
+ *  'last_domain' is the maximum state number used as domain image.
+ *
+ *  Return value:
+ *	number of non-zero matrix elements (WFA edges)
+ */
+{
+   range_sort_t	rs;			/* ranges are sorted as in the coder */
+   unsigned	max_domain;		/* dummy used for recursion */
+   unsigned	total = 0;
+      
+   /*
+    *  Generate a list of range blocks.
+    *  The order is the same as in the coder.
+    */
+   rs.range_state      = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (u_word_t));
+   rs.range_label      = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (byte_t));
+   rs.range_max_domain = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (u_word_t));
+   rs.range_subdivided = Calloc ((last_domain + 1) * MAXLABELS,
+				 sizeof (bool_t));
+   rs.range_no	       = 0;
+   max_domain 	       = wfa->basis_states - 1;
+   sort_ranges (last_domain, &max_domain, &rs, wfa);
+   
+   /*
+    *  Compute and write distribution of #edges
+    */
+   {
+      unsigned state, label;
+      unsigned edge;
+      unsigned count [MAXEDGES + 1];
+      unsigned n;
+      unsigned edges = 0;
+      unsigned M     = 0;
+      unsigned bits  = bits_processed (output);
+      
+      for (n = 0; n < MAXEDGES + 1; n++)
+	 count [n] = 0;
+      
+      for (state = wfa->basis_states; state <= last_domain; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (isrange (wfa->tree [state][label]))
+	    {
+	       for (edge = 0; isedge (wfa->into [state][label][edge]); edge++)
+		  ;
+	       count [edge]++;
+	       edges++;
+	       M = max (edge, M);
+	    }
+      write_rice_code (M, 3, output);
+      for (n = 0; n <= M; n++)
+/* NETPBM: The following causes a crash when last_domain < 4, because
+   it requests writing of a negative number of bits.  And we have seen
+   last_domain = 3.  But we have no clue what last_domain means, or 
+   even what a rice code is, so we don't know where the error lies.
+   -Bryan 2001.02.09 
+*/
+	 write_rice_code (count [n], (int) log2 (last_domain) - 2, output);
+
+      /*
+       * Arithmetic coding of values */
+      {
+	 unsigned  range;
+	 model_t  *elements = alloc_model (M + 1, 0, 0, count);
+	 arith_t  *encoder  = alloc_encoder (output);
+	       
+	 for (range = 0; range < rs.range_no; range++)
+	    if (!rs.range_subdivided [range])
+	    {
+	       state = rs.range_state [range];
+	       label = rs.range_label [range];
+	       for (edge = 0; isedge (wfa->into [state][label][edge]); edge++)
+		  ;
+	       
+	       encode_symbol (edge, encoder, elements);
+	    }
+	 free_encoder (encoder);
+	 free_model (elements);
+      }
+      debug_message ("delta-#edges: %5d bits. (%5d symbols => %5.2f bps)",
+		     bits_processed (output) - bits, edges,
+		     edges > 0 ? ((bits_processed (output) - bits) /
+				  (double) edges) : 0);
+   }
+
+   /*
+    *  Write matrix elements
+    */
+   {
+      unsigned	bits  	 = bits_processed (output);
+      u_word_t *mapping1 = Calloc (wfa->states, sizeof (u_word_t));
+      u_word_t *mapping2 = Calloc (wfa->states, sizeof (u_word_t));
+      unsigned	range;
+
+      put_bit (output, use_normal_domains);
+      put_bit (output, use_delta_domains);
+      
+      /*
+       *  Generate array of states which are admitted domains.
+       *  When coding intra frames 'mapping1' == 'mapping2' otherwise
+       *  'mapping1' is a list of 'normal' domains which are admitted for 
+       *             coding intra blocks
+       *  'mapping2' is a list of 'delta' domains which are admitted for
+       *             coding the motion compensated prediction error 
+       */
+      {
+	 unsigned n1, n2, state;
+	 
+	 for (n1 = n2 = state = 0; state < wfa->states; state++)
+	 {
+	    mapping1 [state] = n1;
+	    if (usedomain (state, wfa)
+		&& (state < wfa->basis_states || use_delta_domains
+		    || !wfa->delta_state [state]))
+	       n1++;
+	    
+	    mapping2 [state] = n2;
+	    if (usedomain (state, wfa)
+		&& (state < wfa->basis_states || use_normal_domains
+		    || wfa->delta_state [state]))
+	       n2++;
+	 }
+	 debug_message ("# normal states = %d, # delta states = %d,"
+			" # WFA states = %d", n1, n2, wfa->states);
+      }
+      
+      for (range = 0; range < rs.range_no; range++)
+	 if (!rs.range_subdivided [range])
+	 {
+	    unsigned  state = rs.range_state [range];
+	    unsigned  label = rs.range_label [range];
+	    unsigned  last  = 1;
+	    u_word_t *mapping;
+	    unsigned  max_value;
+	    unsigned  edge;
+	    word_t    domain;
+
+	    if (wfa->delta_state [state] ||
+		wfa->mv_tree [state][label].type != NONE)
+	       mapping = mapping2;
+	    else
+	       mapping = mapping1;
+	    
+	    max_value = mapping [rs.range_max_domain [range]];
+	    
+	    for (edge = 0; isedge (domain = wfa->into [state][label][edge]);
+		 edge++)
+	       if (domain > 0)
+	       {
+		  total++;
+		  if (max_value - last)
+		  {
+		     write_bin_code (mapping [domain] - last,
+				     max_value - last, output);
+		     last = mapping [domain] + 1;
+		  }
+	       }
+	 }
+
+      debug_message ("delta-index:  %5d bits. (%5d symbols => %5.2f bps)",
+		     bits_processed (output) - bits, total,
+		     total > 0 ? ((bits_processed (output) - bits) /
+				  (double) total) : 0);
+      Free (mapping1);
+      Free (mapping2);
+   }
+   
+   Free (rs.range_state);
+   Free (rs.range_label);
+   Free (rs.range_max_domain);
+   Free (rs.range_subdivided);
+
+   return total;
+}
+
+static unsigned
+column_0_encoding (const wfa_t *wfa, unsigned last_row, bitfile_t *output)
+/*
+ *  Write column 0 of the transition matrices of the 'wfa' to stream 'output'
+ *  with quasi arithmetic coding.
+ *  All rows from 'wfa->basis_states' up to 'last_row' are decoded.
+ *
+ *  Return value:
+ *	number of non-zero matrix elements (WFA edges)
+ */
+{
+   u_word_t  high;			/* Start of the current code range */
+   u_word_t  low;			/* End of the current code range */
+   unsigned *prob;			/* probability array */
+   unsigned  row;			/* current matrix row */
+   unsigned  label;			/* current matrix label */
+   unsigned  underflow;			/* Underflow bits */
+   unsigned  index;			/* probability index */
+   unsigned  total = 0;			/* Number of '1' elements */
+   unsigned  bits  = bits_processed (output);
+
+   /*
+    *  Compute the probability array:
+    *  prob[] = { 1/2, 1/2, 1/4, 1/4, 1/4, 1/4,
+    *             1/8, ... , 1/16, ..., 1/(MAXPROB+1)}
+    */
+   {
+      unsigned n;
+      unsigned exp;			/* current exponent */
+      
+      prob = Calloc (1 << (MAX_PROB + 1), sizeof (unsigned));
+   
+      for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++)
+	 for (exp = 0; exp < 1U << n; exp++, index++)
+	    prob [index] = n;
+   }
+   
+   high      = HIGH;			/* 1.0 */
+   low       = LOW;			/* 0.0 */
+   underflow = 0;			/* no underflow bits */
+
+   index = 0;
+
+   /*
+    *  Encode column 0 with a quasi arithmetic coder (QAC).
+    *  Advantage of this QAC with respect to a binary AC:
+    *  Instead of using time consuming multiplications and divisions
+    *  to compute the probability of the most probable symbol (MPS) and
+    *  the range of the interval, a table look up procedure linked
+    *  with a shift operation is used for both computations.
+    */
+   for (row = wfa->basis_states; row <= last_row; row++)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (isrange (wfa->tree [row][label]))
+	 {
+	    if (wfa->into [row][label][0] != 0)
+	    {
+	       /*
+		*  encode the MPS '0'
+		*/
+	       high = high - ((high - low) >> prob [index]) - 1;
+	       RESCALE_OUTPUT_INTERVAL;
+	       
+	       if (index < 1020)
+		  index++;
+	    }
+	    else
+	    {
+	       /*
+		*  encode the LPS '1'
+		*/
+	       low = high - ((high - low) >> prob [index]);
+
+	       RESCALE_OUTPUT_INTERVAL;
+	       
+	       total++;
+	       index >>= 1;
+	    }
+	 }
+   /*
+    *  Flush the quasi-arithmetic encoder
+    */
+   low = high;
+
+   RESCALE_OUTPUT_INTERVAL;
+   
+   OUTPUT_BYTE_ALIGN (output);
+
+   Free (prob);
+
+   debug_message ("delta-state0: %5d bits. (%5d symbols => %5.2f bps)",
+		  bits_processed (output) - bits, total,
+		  total > 0 ? ((bits_processed (output) - bits) /
+			       (double) total) : 0);
+
+   return total;
+}   
+
+static unsigned
+chroma_encoding (const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write transition matrices of 'wfa' states which are part of the
+ *  chroma channels Cb and Cr to stream 'output'.
+ *
+ *  Return value:
+ *	number of non-zero matrix elements (WFA edges)
+ */
+{
+
+   unsigned  domain;			/* current domain, counter */
+   unsigned  label;			/* current label */
+   unsigned  total = 0;			/* number of '1' elements */
+   u_word_t  high;			/* Start of the current code range */
+   u_word_t  low;			/* End of the current code range */
+   unsigned  underflow;			/* underflow bits */
+   unsigned *prob;			/* probability array */
+   unsigned  index;			/* probability index, counter */
+   unsigned  next_index;		/* probability of last domain */
+   unsigned  row;			/* current matrix row */
+   word_t   *y_domains;
+   unsigned  count = 0;			/* number of transitions for part 1 */
+   unsigned  bits  = bits_processed (output);
+   
+   /*
+    *  Compute the asymmetric probability array
+    *  prob[] = { 1/2, 1/2, 1/4, 1/4, 1/4, 1/4,
+    *                     1/8, ... , 1/16, ..., 1/(MAXPROB+1)}
+    */
+   {
+      unsigned n;
+      unsigned exp;			/* current exponent */
+      
+      prob = Calloc (1 << (MAX_PROB + 1), sizeof (unsigned));
+   
+      for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++)
+	 for (exp = 0; exp < 1U << n; exp++, index++)
+	    prob [index] = n;
+   }
+   
+   high      = HIGH;			/* 1.0 */
+   low       = LOW;			/* 0.0 */
+   underflow = 0;			/* no underflow bits */
+
+   next_index = index = 0;
+
+   y_domains = compute_hits (wfa->basis_states,
+			     wfa->tree [wfa->tree [wfa->root_state][0]][0],
+			     wfa->wfainfo->chroma_max_states, wfa);
+
+   /*
+    *  First of all, read all matrix columns given in the list 'y_domains'
+    *  which note all admitted domains.
+    *  These matrix elements are stored with QAC (see column_0_encoding ()).
+    */
+   for (domain = 0; y_domains [domain] != -1; domain++)
+   {
+      bool_t save_index = YES;		/* YES: store current prob. index */
+      
+      row   = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1;
+      index = next_index;
+	 
+      for (; row < wfa->states; row++)
+      {
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (isrange (wfa->tree [row][label]))
+	    {
+	       unsigned	edge;
+	       int	into;
+	       bool_t    match;		/* approx with current domain found */
+	       
+	       for (match = NO, edge = 0;
+		    isedge (into = wfa->into [row][label][edge])
+			    && (unsigned) into < row;
+		    edge++)
+		  if (into == y_domains [domain]
+		      && into != wfa->y_state [row][label])
+		     match = YES;
+	       if (!match)
+	       {
+		  /*
+		   *  encode the MPS '0'
+		   */
+		  high = high - ((high - low) >> prob [index]) - 1;
+
+		  RESCALE_OUTPUT_INTERVAL;
+		     
+		  if (index < 1020)
+		     index++;
+	       }
+	       else
+	       {
+		  /*
+		   *  encode the LPS '1'
+		   */
+		  low = high - ((high - low) >> prob [index]);
+
+		  RESCALE_OUTPUT_INTERVAL;
+		     
+		  total++;
+		  index >>= 1;
+	       }
+	    }
+	 if (save_index)
+	 {
+	    next_index = index;
+	    save_index = NO;
+	 }
+      }
+   }
+
+   debug_message ("CbCr_matrix:  %5d bits. (%5d symbols => %5.2f bps)",
+		  bits_processed (output) - bits, total,
+		  total > 0 ? ((bits_processed (output) - bits) /
+			       (double) total) : 0);
+   count = total;
+   bits  = bits_processed (output);
+   
+   /*
+    *  Encode the additional column which indicates whether there
+    *  are transitions to a state with same spatial coordinates
+    *  in the Y component.
+    *
+    *  Again, quasi arithmetic coding is used for this task.
+    */
+
+   next_index = index = 0;
+
+   for (row = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1;
+	row < wfa->states; row++)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (!wfa->y_column [row][label])
+	 {
+	    /*
+	     *  encode the MPS '0'
+	     */
+	    high = high - ((high - low) >> prob [index]) - 1;
+
+	    RESCALE_OUTPUT_INTERVAL;
+	    
+	    if (index < 1020)
+	       index++;
+	 }
+	 else
+	 {
+	    /*
+	     *  encode the LPS '1'
+	     */
+	    low = high - ((high - low) >> prob [index]);
+
+	    RESCALE_OUTPUT_INTERVAL;
+
+	    index >>= 1;
+	    total++;
+	 }
+
+   /*
+    *  Flush the quasi-arithmetic encoder
+    */
+   low = high;
+
+   RESCALE_OUTPUT_INTERVAL;
+   OUTPUT_BYTE_ALIGN (output);
+
+   debug_message ("Yreferences:  %5d bits. (%5d symbols => %5.2f bps)",
+		  bits_processed (output) - bits, total - count,
+		  total - count > 0 ? ((bits_processed (output) - bits) /
+				       (double) (total - count)) : 0);
+
+   Free (prob);
+   Free (y_domains);
+   
+   return total;
+}
diff --git a/converter/other/fiasco/output/matrices.h b/converter/other/fiasco/output/matrices.h
new file mode 100644
index 00000000..f880fef8
--- /dev/null
+++ b/converter/other/fiasco/output/matrices.h
@@ -0,0 +1,28 @@
+/*
+ *  matrices.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MATRICES_H
+#define _MATRICES_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+unsigned
+write_matrices (bool_t use_normal_domains, bool_t use_delta_domains,
+		const wfa_t *wfa, bitfile_t *output);
+
+#endif /* _MATRICES_H */
+
diff --git a/converter/other/fiasco/output/mc.c b/converter/other/fiasco/output/mc.c
new file mode 100644
index 00000000..afff586b
--- /dev/null
+++ b/converter/other/fiasco/output/mc.c
@@ -0,0 +1,250 @@
+/*
+ *  mc.c:		Output of motion compensation	
+ *
+ *  Written by:		Michael Unger
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "bit-io.h"
+#include "mvcode.h"
+
+#include "mc.h"
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+static unsigned p_frame_codes [4][2] =
+/*
+ *  Code values and bits for P-frame prediction
+ *  NONE,  FORWARD
+ */
+{
+   {1, 1}, {0, 1}, {0, 0}, {0, 0} 
+};
+
+static unsigned b_frame_codes [4][2] =
+/*
+ *  Code values and bits for B-frame prediction
+ *  NONE,  FORWARD,  BACKWARD, INTERPOLATED
+ */
+{
+   {1, 1}, {000, 3}, {001, 3}, {01, 2} 
+};
+
+enum vlc_e {CODE = 0, BITS = 1};
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+encode_mc_tree (unsigned max_state, frame_type_e frame_type, const wfa_t *wfa,
+	       bitfile_t *output);
+static void
+encode_mc_coords (unsigned max_state, const wfa_t *wfa, bitfile_t *output);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+write_mc (frame_type_e frame_type, const wfa_t *wfa, bitfile_t *output)
+{
+   unsigned max_state = wfa->wfainfo->color
+			? wfa->tree[wfa->tree[wfa->root_state][0]][0]
+			: wfa->states;
+
+   encode_mc_tree (max_state, frame_type, wfa, output);
+   encode_mc_coords (max_state, wfa, output);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+encode_mc_tree (unsigned max_state, frame_type_e frame_type, const wfa_t *wfa,
+		bitfile_t *output)
+/*
+ *  Write tree of motion compensation decisions to the 'output' stream.
+ *  Depending on 'frame_type' different decoding methods are used.
+ *  'max_state' is the last state with motion compensation infos.
+ *
+ *  No return value.
+ */
+{
+   unsigned  label;			/* current label */
+   unsigned  state;			/* current state */
+   unsigned  total = 0;			/* number of motion tree decisions */
+   unsigned  queue [MAXSTATES];		/* state numbers in BFO */
+   unsigned  current;			/* current node to process */
+   unsigned  last;			/* last node (update every new node) */
+   mc_type_e type;			/* type of motion compensation */
+   unsigned	     (*mc_tree_codes)[2]; /* pointer to VLC table */
+   unsigned  bits  = bits_processed (output); /* number of bits used */
+   
+   if (frame_type == P_FRAME)
+      mc_tree_codes = p_frame_codes;	/* binary code */
+   else 
+      mc_tree_codes = b_frame_codes;	/* variable length code */
+   
+   /*
+    *  Traverse tree in breadth first order (starting at
+    *  level 'wfa->p_max_level'). Use a queue to store the childs
+    *  of each node ('last' is the next free queue element).  
+    */
+
+   for (last = 0, state = wfa->basis_states; state < max_state; state++)
+      if (wfa->level_of_state [state] - 1 == (int) wfa->wfainfo->p_max_level)
+	 queue [last++] = state;	/* init level = 'mc_max_level' */
+   
+   for (current = 0; current < last; current++)
+      for (label = 0; label < MAXLABELS; label++)
+      {
+	 state = queue [current];
+	 type  = wfa->mv_tree [state][label].type;
+	 if (wfa->x [state][label]
+	     + width_of_level (wfa->level_of_state [state] - 1)
+	     <= wfa->wfainfo->width
+	     &&
+	     wfa->y [state][label]
+	     + height_of_level (wfa->level_of_state [state] - 1)
+	     <= wfa->wfainfo->height)
+	 {
+	    put_bits (output, mc_tree_codes [type][CODE],
+		      mc_tree_codes [type][BITS]);
+	    total++;
+	 }
+	 if (type == NONE && !isrange (wfa->tree [state][label]) &&
+	     wfa->level_of_state [state] - 1 >=
+	     (int) wfa->wfainfo->p_min_level)
+	    queue [last++] = wfa->tree [state][label]; /* append child */
+	 
+      }
+
+   OUTPUT_BYTE_ALIGN (output);
+   debug_message ("mc-tree:      %5d bits. (%5d symbols => %5.2f bps)",
+		  bits_processed (output) - bits, total,
+		  total > 0 ? ((bits_processed (output) - bits) /
+			       (double) total) : 0);
+}
+
+static void
+encode_mc_coords (unsigned max_state, const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write motion vector coordinates to the 'output' stream. They are stored
+ *  with the static Huffman code of the MPEG and H.263 standards.
+ *  'max_state' is the last state with motion compensation infos.
+ *
+ *  No return value.
+ */
+{
+   unsigned  state;			/* current state */
+   unsigned  label;			/* current label */
+   unsigned  level_count [MAXLEVEL];	/* number of mv per level */
+   unsigned  level;			/* counter */
+   unsigned  ftotal = 0;		/* #forward motion tree decisions */
+   unsigned  btotal = 0;		/* #backward decisions */
+   unsigned  itotal = 0;		/* #interpolated decisions */
+   unsigned  bits   = bits_processed (output); /* number of bits used */
+   unsigned  sr     = wfa->wfainfo->search_range; /* search range */
+   
+   for (level = wfa->wfainfo->p_max_level;
+	level >= wfa->wfainfo->p_min_level; level--)
+      level_count [level] = 0;
+   
+   for (state = wfa->basis_states; state < max_state; state++)
+      for (label = 0; label < MAXLABELS; label++)
+      {
+	 mv_t *mv = &wfa->mv_tree[state][label]; /* motion vector info */
+	 
+	 if (mv->type != NONE)
+	 {
+	    level_count [wfa->level_of_state [state] - 1]++;
+	    switch (mv->type)
+	    {
+	       case FORWARD:
+		  put_bits (output,
+			    mv_code_table[(mv->fx + sr)][CODE],
+			    mv_code_table[(mv->fx + sr)][BITS]);
+		  put_bits (output,
+			    mv_code_table[(mv->fy + sr)][CODE],
+			    mv_code_table[(mv->fy + sr)][BITS]);
+		  ftotal++;
+		  break;
+	       case BACKWARD:
+		  put_bits (output,
+			    mv_code_table[(mv->bx + sr)][CODE],
+			    mv_code_table[(mv->bx + sr)][BITS]);
+		  put_bits (output,
+			    mv_code_table[(mv->by + sr)][CODE],
+			    mv_code_table[(mv->by + sr)][BITS]);
+		  btotal++;
+		  break;
+	       case INTERPOLATED:
+		  put_bits (output,
+			    mv_code_table[(mv->fx + sr)][CODE],
+			    mv_code_table[(mv->fx + sr)][BITS]);
+		  put_bits (output,
+			    mv_code_table[(mv->fy + sr)][CODE],
+			    mv_code_table[(mv->fy + sr)][BITS]);
+		  put_bits (output,
+			    mv_code_table[(mv->bx + sr)][CODE],
+			    mv_code_table[(mv->bx + sr)][BITS]);
+		  put_bits (output,
+			    mv_code_table[(mv->by + sr)][CODE],
+			    mv_code_table[(mv->by + sr)][BITS]);
+		  itotal++;
+		  break;
+	       default:
+		  break;
+	    }
+	 }
+      }
+
+   OUTPUT_BYTE_ALIGN (output);
+   
+   debug_message ("Motion compensation: %d forward, %d backward, "
+		  "%d interpolated", ftotal, btotal, itotal);
+
+   for (level = wfa->wfainfo->p_max_level;
+	level >= wfa->wfainfo->p_min_level; level--)
+      debug_message ("Level %d: %d motion vectors", level, level_count[level]);
+   
+   {
+      unsigned  total = ftotal * 2 + btotal * 2 + itotal * 4;
+
+      debug_message ("mv-coord:     %5d bits. (%5d symbols => %5.2f bps)",
+		     bits_processed (output) - bits, total,
+		     total > 0 ? ((bits_processed (output) - bits) /
+				  (double) total) : 0);
+   }
+
+   return;
+}
diff --git a/converter/other/fiasco/output/mc.h b/converter/other/fiasco/output/mc.h
new file mode 100644
index 00000000..b7843fd8
--- /dev/null
+++ b/converter/other/fiasco/output/mc.h
@@ -0,0 +1,28 @@
+/*
+ *  mc.h
+ *
+ *  Written by:		Michael Unger
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _MC_H
+#define _MC_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+void
+write_mc (frame_type_e frame_type, const wfa_t *wfa, bitfile_t *output);
+
+#endif /* not _MC_H */
+
diff --git a/converter/other/fiasco/output/nd.c b/converter/other/fiasco/output/nd.c
new file mode 100644
index 00000000..a09ff762
--- /dev/null
+++ b/converter/other/fiasco/output/nd.c
@@ -0,0 +1,244 @@
+/*
+ *  nd.c:		Output of prediction tree	
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "arith.h"
+#include "misc.h"
+#include "bit-io.h"
+#include "rpf.h"
+#include "list.h"
+
+#include "nd.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static unsigned
+encode_nd_tree (const wfa_t *wfa, bitfile_t *output);
+static void
+encode_nd_coefficients (unsigned total, const wfa_t *wfa, bitfile_t *output);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+write_nd (const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write prediction information of 'wfa' to given stream 'output'.
+ *  Coefficients are quantized with model 'p_rpf'.
+ *
+ *  No return value.
+ */
+{
+   unsigned total = encode_nd_tree (wfa, output);
+   
+   if (total > 0)
+      encode_nd_coefficients (total, wfa, output);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static unsigned
+encode_nd_tree (const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write prediction tree of 'wfa' to given stream 'output'. 
+ *
+ *  No return value.
+ */
+{
+   lqueue_t *queue;			/* queue of states */
+   int	     state, next;		/* state and its current child */
+   unsigned  used, not_used;		/* counter ND used/not used */
+   u_word_t  low;			/* Start of the current code range */
+   u_word_t  high;			/* End of the current code range */
+   u_word_t  underflow;			/* Number of underflow bits pending */
+   u_word_t  sum0, sum1;		/* Probability model */
+   unsigned  bits = bits_processed (output);
+
+   used = not_used = 0;
+   
+   /*
+    *  Initialize arithmetic coder
+    */
+   low       = 0;
+   high      = 0xffff;
+   underflow = 0;
+   sum0      = 1;
+   sum1      = 11;
+   
+   queue = alloc_queue (sizeof (int));
+   state = wfa->root_state;
+   queue_append (queue, &state);
+   
+   /*
+    *  Traverse the WFA tree in breadth first order (using a queue).
+    */
+   while (queue_remove (queue, &next))
+   {
+      unsigned label;
+      
+      if (wfa->level_of_state [next] > wfa->wfainfo->p_max_level + 1)
+      {
+	 /*
+	  *  Nondetermismn is not allowed at levels larger than
+	  *  'wfa->wfainfo->p_max_level'.
+	  */
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (ischild (state = wfa->tree [next][label]))
+	       queue_append (queue, &state); /* continue with childs */
+      }
+      else if (wfa->level_of_state [next] > wfa->wfainfo->p_min_level)
+      {
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (ischild (state = wfa->tree [next][label]))
+	    {
+	       unsigned range;		/* Current interval range */
+
+	       if (isedge (wfa->into [next][label][0])) /* prediction used */
+	       {
+		  used++;
+		  
+		  /*
+		   *  Encode a '1' symbol
+		   */
+		  range =  (high - low) + 1;
+		  low   = low + (u_word_t) ((range * sum0) / sum1);
+		  RESCALE_OUTPUT_INTERVAL;
+	       }
+	       else			/* no predict., continue with childs */
+	       {
+		  not_used++;
+		  if (wfa->level_of_state [state] > wfa->wfainfo->p_min_level)
+		     queue_append (queue, &state);
+		  
+		  /*
+		   *  Encode a '0' symbol
+		   */
+		  range =  (high - low) + 1;
+		  high  = low + (u_word_t) ((range * sum0) / sum1 - 1);
+		  RESCALE_OUTPUT_INTERVAL;
+		  sum0++;
+	       }
+	       /*
+		*  Update the frequency counts
+		*/
+	       sum1++;
+	       if (sum1 > 50)		/* Scale the symbol frequencies */
+	       {
+		  sum0 >>= 1;
+		  sum1 >>= 1;
+		  if (!sum0)
+		     sum0 = 1;
+		  if (sum0 >= sum1)
+		     sum1 = sum0 + 1;
+	       }
+	    }
+	 
+      }
+   }
+   free_queue (queue);
+
+   /*
+    *  Flush the quasi-arithmetic encoder
+    */
+   low = high;
+   RESCALE_OUTPUT_INTERVAL;
+   OUTPUT_BYTE_ALIGN (output);
+
+   debug_message ("%d nd fields: %d used nd, %d used not nd", used + not_used,
+		  used, not_used);
+   {
+      unsigned total = used + not_used;
+      
+      debug_message ("nd-tree:      %5d bits. (%5d symbols => %5.2f bps)",
+		     bits_processed (output) - bits, total,
+		     total > 0 ? ((bits_processed (output) - bits) /
+				  (double) total) : 0);
+   }
+
+   return used;
+}
+
+static void
+encode_nd_coefficients (unsigned total, const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write #'total' weights of nondeterministic part of 'wfa' to given 'output'
+ *  stream. Coefficients are stored with arithmetic coding (the model is
+ *  given by 'p_rpf').
+ *
+ *  No return value.
+ */
+{
+   unsigned bits = bits_processed (output);
+
+   {
+      unsigned *coefficients;		/* array of factors to encode */
+      unsigned *ptr;			/* pointer to current factor */
+      unsigned	state, label, edge;
+      word_t	domain;
+      
+      ptr = coefficients  = Calloc (total, sizeof (unsigned));
+
+      for (state = wfa->basis_states; state < wfa->states; state++)
+	 for (label = 0; label < MAXLABELS; label++)
+	    if (ischild (wfa->tree [state][label])
+		&& isedge (wfa->into [state][label][0]))
+	       for (edge = 0; isedge (domain = wfa->into [state][label][edge]);
+		    edge++)
+	       {
+		  if (ptr - coefficients >= (int) total)
+		     error ("Can't write more than %d coefficients.", total);
+
+		  *ptr++ = rtob (wfa->weight [state][label][edge],
+				 wfa->wfainfo->dc_rpf);
+	       }
+
+      /*
+       *  Encode array of coefficients with arithmetic coding
+       */
+      {
+	 const int scaling = 50;	/* scaling factor of prob. model */
+	 unsigned  c_symbols = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1);
+
+	 encode_array (output, coefficients, NULL, &c_symbols, 1,
+		       total, scaling);
+      }
+      
+      debug_message ("nd-factors:   %5d bits. (%5d symbols => %5.2f bps)",
+		     bits_processed (output) - bits, total,
+		     total ? ((bits_processed (output) - bits)
+			      / (double) total) : 0);
+      Free (coefficients);
+   }
+}
+
+
diff --git a/converter/other/fiasco/output/nd.h b/converter/other/fiasco/output/nd.h
new file mode 100644
index 00000000..600b3d73
--- /dev/null
+++ b/converter/other/fiasco/output/nd.h
@@ -0,0 +1,27 @@
+/*
+ *  nd.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _ND_H
+#define _ND_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+void
+write_nd (const wfa_t *wfa, bitfile_t *output);
+
+#endif /* not _ND_H */
+
diff --git a/converter/other/fiasco/output/tree.c b/converter/other/fiasco/output/tree.c
new file mode 100644
index 00000000..0056d7dd
--- /dev/null
+++ b/converter/other/fiasco/output/tree.c
@@ -0,0 +1,176 @@
+/*
+ *  tree.c:		Output of bintree partitioning
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "bit-io.h"
+#include "arith.h"
+#include "misc.h"
+
+#include "tree.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+encode_tree (bitfile_t *output, const byte_t *data, unsigned n_data,
+	     unsigned scaling, u_word_t sum0, u_word_t sum1);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+write_tree (const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Write bintree to stream 'output'.
+ *  Traverse tree in breadth first order and save a '1' for each child
+ *  and a '0' for each range image.
+ *
+ *  No return value.
+ */
+{
+   unsigned  queue [MAXSTATES];		/* state numbers in BFO */
+   unsigned  current;			/* current node to process */
+   unsigned  last;			/* last node (update every new node) */
+   unsigned  label;			/* current label */
+   int	     into;			/* next child */
+   byte_t   *tree_string;		/* bitstring to encode */
+   unsigned  total = 0;			/* number of ranges */
+   unsigned  bits  = bits_processed (output); /* number of bits */
+
+   /*
+    *  Traverse tree in breadth first order. Use a queue to store
+    *  the childs of each node ('last' is the next free queue element).
+    *  The first element ('current') of this queue will get the new parent
+    *  node. 
+    */
+   tree_string = Calloc (MAXSTATES * MAXLABELS, sizeof (byte_t));
+   queue [0] = wfa->root_state;
+   for (last = 1, current = 0; current < last; current++)
+      for (label = 0; label < MAXLABELS; label++)
+	 if (!isrange (into = wfa->tree [queue[current]][label])) /* child ? */
+	 {
+	    queue [last++]        = into;
+	    tree_string [total++] = 1;
+	 }
+	 else				/* or range ? */
+	    tree_string [total++] = 0;
+
+   if (total != (wfa->states - wfa->basis_states) * MAXLABELS)
+      error ("total [%d] != (states - basis_states) * 2 [%d]", total,
+	     (wfa->states - wfa->basis_states) * MAXLABELS);
+   
+   {
+      unsigned scale = total / 20 ;
+
+      encode_tree (output, tree_string, total, scale, 1, 11);
+   }
+
+   Free (tree_string);
+   
+   debug_message ("tree:         %5d bits. (%5d symbols => %5.2f bps)",
+		  bits_processed (output) - bits, total,
+		  total > 0 ? ((bits_processed (output) - bits)
+			       / (double) total) : 0);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+encode_tree (bitfile_t *output, const byte_t *data, unsigned n_data,
+	     unsigned scaling, u_word_t sum0, u_word_t sum1)
+/*
+ *  Encode bintree data with adaptive binary arithmetic coding.
+ *  Write 'n_data' output symbols stored in 'data' to stream 'output'.
+ *  Rescale probability model after every 'scaling' symbols.
+ *  Initial counts are given by 'sum0' and 'sum1'.
+ *
+ *  No return value.
+ */
+{
+   u_word_t low;			/* Start of the current code range */
+   u_word_t high;			/* End of the current code range */
+   u_word_t underflow;			/* Number of underflow bits pending */
+   unsigned n;				/* Data counter */
+
+   low       = 0;
+   high      = 0xffff;
+   underflow = 0;
+
+   for (n = n_data; n; n--)
+   {
+      unsigned range;			/* Current interval range */
+      
+      if (!*data++)
+      {
+	 /*
+	  *  encode a '0'
+	  */
+	 range =  (high - low) + 1;
+	 high  = low + (u_word_t) ((range * sum0) / sum1 - 1);
+
+	 RESCALE_OUTPUT_INTERVAL;
+
+	 sum0++;
+      }
+      else
+      {
+	 /*
+	  *  encode a '1'
+	  */
+	 range =  (high - low) + 1;
+	 low   = low + (u_word_t) ((range * sum0) / sum1);
+
+	 RESCALE_OUTPUT_INTERVAL;
+      }
+      /*
+       *  Update the frequency counts
+       */
+      sum1++;
+      if (sum1 > scaling) /* Scale the symbol frequencies */
+      {
+	 sum0 >>= 1;
+	 sum1 >>= 1;
+	 if (!sum0)
+	    sum0 = 1;
+	 if (sum0 >= sum1)
+	    sum1 = sum0 + 1;
+      }
+   }
+   /*
+    *  Flush the quasi-arithmetic encoder
+    */
+   low = high;
+
+   RESCALE_OUTPUT_INTERVAL;
+
+   OUTPUT_BYTE_ALIGN (output);
+}
diff --git a/converter/other/fiasco/output/tree.h b/converter/other/fiasco/output/tree.h
new file mode 100644
index 00000000..6f8a3800
--- /dev/null
+++ b/converter/other/fiasco/output/tree.h
@@ -0,0 +1,27 @@
+/*
+ *  tree.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _TREE_H
+#define _TREE_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+void
+write_tree (const wfa_t *wfa, bitfile_t *output);
+
+#endif /* not _TREE_H */
+
diff --git a/converter/other/fiasco/output/weights.c b/converter/other/fiasco/output/weights.c
new file mode 100644
index 00000000..085a1f00
--- /dev/null
+++ b/converter/other/fiasco/output/weights.c
@@ -0,0 +1,200 @@
+/*
+ *  weights.c:		Output of weights
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "wfa.h"
+#include "misc.h"
+#include "bit-io.h"
+#include "arith.h"
+#include "wfalib.h"
+
+#include "weights.h"
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+void
+write_weights (unsigned total, const wfa_t *wfa, bitfile_t *output)
+/*
+ *  Traverse the transition matrices of the 'wfa' and write #'total'
+ *  weights != 0 to stream 'output'.
+ *
+ *  No return value.
+ */
+{
+   unsigned  state, label;		/* current label */
+   unsigned  offset1, offset2;		/* model offsets. */
+   unsigned  offset3, offset4;		/* model offsets. */
+   unsigned *weights_array;		/* array of weights to encode */
+   unsigned *wptr;			/* pointer to current weight */
+   unsigned *level_array;		/* array of corresponding levels */
+   unsigned *lptr;			/* pointer to current corr. level */
+   int	     min_level, max_level;	/* min and max range level */
+   int	     d_min_level, d_max_level; 	/* min and max delta range level */
+   bool_t    dc, d_dc;			/* true if dc or delta dc are used */
+   bool_t    delta_approx = NO;		/* true if delta has been used */
+   unsigned  delta_count  = 0;		/* number of delta ranges */
+   unsigned  bits 	  = bits_processed (output);
+   
+   /*
+    *  Check whether delta approximation has been used
+    */
+   for (state = wfa->basis_states; state < wfa->states; state++)
+      if (wfa->delta_state [state])
+      {
+	 delta_approx = YES;
+	 break;
+      }
+   
+   /*
+    *  Generate array of corresponding levels (context of probability model)
+    */
+   min_level = d_min_level = MAXLEVEL;
+   max_level = d_max_level = 0;
+   dc 	     = d_dc	   = NO;
+   
+   for (state = wfa->basis_states; state < wfa->states; state++)
+      for (label = 0; label < MAXLABELS; label++)
+         if (isrange (wfa->tree [state][label]))
+	 {
+	    if (delta_approx && wfa->delta_state [state]) /* delta approx. */
+	    {
+	       d_min_level = min (d_min_level,
+				  wfa->level_of_state [state] - 1);
+	       d_max_level = max (d_max_level,
+				  wfa->level_of_state [state] - 1);
+	       if (wfa->into [state][label][0] == 0)
+		  d_dc = YES;
+	    }
+	    else
+	    {
+	       min_level = min (min_level, wfa->level_of_state [state] - 1);
+	       max_level = max (max_level, wfa->level_of_state [state] - 1);
+	       if (wfa->into [state][label][0] == 0)
+		  dc = YES;
+	    }
+	 }
+   if (min_level > max_level)		/* no lc found */
+      max_level = min_level - 1;
+   if (d_min_level > d_max_level)
+      d_max_level = d_min_level - 1;
+
+   /*
+    *  Context model:
+    *		0		DC weight
+    *		1		Delta DC weight
+    *		2-k		normal weights per level
+    *		k+1 - m		Delta weights per level
+    */
+
+   offset1 = dc ? 1 : 0;
+   offset2 = offset1 + (d_dc ? 1 : 0);
+   offset3 = offset2 + (max_level - min_level + 1);
+   offset4 = offset3 + (d_max_level - d_min_level + 1);
+   
+   /*
+    *  Weights are encoded as follows:
+    *  all weights of state n
+    *     sorted by label
+    *        sorted by domain number
+    */
+
+   wptr = weights_array = Calloc (total, sizeof (unsigned));
+   lptr = level_array   = Calloc (total, sizeof (unsigned));
+
+   for (state = wfa->basis_states; state < wfa->states; state++)
+      for (label = 0; label < MAXLABELS; label++)
+         if (isrange (wfa->tree [state][label]))
+	 {
+	    int	edge;			/* current edge */
+	    int	domain;			/* current domain (context of model) */
+	    
+            for (edge = 0; isedge (domain = wfa->into [state][label][edge]);
+		 edge++)
+            {
+	       if (wptr - weights_array >= (int) total)
+		  error ("Can't write more than %d weights.", total);
+	       if (domain)		/* not DC component */
+	       {
+		  if (delta_approx && wfa->delta_state [state]) /* delta */
+		  {
+		     *wptr++ = rtob (wfa->weight [state][label][edge],
+				     wfa->wfainfo->d_rpf);
+		     *lptr++ = offset3
+			       + wfa->level_of_state [state] - 1 - d_min_level;
+		     delta_count++;
+		  }
+		  else
+		  {
+		     *wptr++ = rtob (wfa->weight [state][label][edge],
+				     wfa->wfainfo->rpf);
+		     *lptr++ = offset2
+			       + wfa->level_of_state [state] - 1 - min_level;
+		  }
+	       }
+	       else			/* DC component */
+	       {
+		  if (delta_approx && wfa->delta_state [state]) /* delta */
+		  {
+		     *wptr++ = rtob (wfa->weight [state][label][edge],
+				     wfa->wfainfo->d_dc_rpf);
+		     *lptr++ = offset1;
+		  }
+		  else
+		  {
+		     *wptr++ = rtob (wfa->weight [state][label][edge],
+				     wfa->wfainfo->dc_rpf);
+		     *lptr++ = 0;
+		  }
+	       }
+            }
+	 }
+
+   {
+      unsigned	 i;
+      unsigned	*c_symbols = Calloc (offset4, sizeof (int));
+      const int	 scale 	   = 500;	/* scaling of probability model */
+
+      c_symbols [0] = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1);
+      if (offset1 != offset2)
+	 c_symbols [offset1] = 1 << (wfa->wfainfo->d_dc_rpf->mantissa_bits
+				     + 1);
+      for (i = offset2; i < offset3; i++)
+	 c_symbols [i] = 1 << (wfa->wfainfo->rpf->mantissa_bits + 1);
+      for (; i < offset4; i++)
+	 c_symbols [i] = 1 << (wfa->wfainfo->d_rpf->mantissa_bits + 1);
+      
+      encode_array (output, weights_array, level_array, c_symbols, offset4,
+		    total, scale);
+      Free (c_symbols);
+   }
+   
+   debug_message ("%d delta weights out of %d.", delta_count, total);
+   debug_message ("weights:      %5d bits. (%5d symbols => %5.2f bps)",
+		  bits_processed (output) - bits, total,
+		  (bits_processed (output) - bits) / (double) total);
+
+   Free (weights_array);
+   Free (level_array);
+}
diff --git a/converter/other/fiasco/output/weights.h b/converter/other/fiasco/output/weights.h
new file mode 100644
index 00000000..271203ad
--- /dev/null
+++ b/converter/other/fiasco/output/weights.h
@@ -0,0 +1,27 @@
+/*
+ *  weights.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:50:31 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef _WEIGHTS_H
+#define _WEIGHTS_H
+
+#include "wfa.h"
+#include "bit-io.h"
+
+void
+write_weights (unsigned total, const wfa_t *wfa, bitfile_t *output);
+
+#endif /* not _WEIGHTS_H */
+
diff --git a/converter/other/fiasco/output/write.c b/converter/other/fiasco/output/write.c
new file mode 100644
index 00000000..e6185ad3
--- /dev/null
+++ b/converter/other/fiasco/output/write.c
@@ -0,0 +1,250 @@
+/*
+ *  write.c:        Output of WFA files
+ *
+ *  Written by:     Ullrich Hafner
+ *      
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/18 15:44:59 $
+ *  $Author: hafner $
+ *  $Revision: 5.3 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+
+#include "types.h"
+#include "macros.h"
+#include "error.h"
+
+#include "cwfa.h"
+#include "image.h"
+#include "misc.h"
+#include "bit-io.h"
+#include "rpf.h"
+
+#include "tree.h"
+#include "matrices.h"
+#include "weights.h"
+#include "mc.h"
+#include "nd.h"
+#include "write.h"
+ 
+/*****************************************************************************
+
+                prototypes
+  
+*****************************************************************************/
+
+static void
+write_tiling (const tiling_t *tiling, bitfile_t *output);
+
+/*****************************************************************************
+
+                public code
+
+                
+*****************************************************************************/
+
+
+void
+write_next_wfa (const wfa_t *wfa, const coding_t *c, bitfile_t *output)
+/*
+ *  Write 'wfa' to stream 'output'. If the first frame should be written
+ *  then also store the header information of the coding struct 'c'.
+ *
+ *  No return value.
+ */
+{
+   unsigned edges = 0;          /* number of transitions */
+   unsigned bits;
+   
+   debug_message ("--------------------------------------"
+          "--------------------------------------");
+
+   if (c->mt->number == 0)              /* first WFA */
+      write_header (wfa->wfainfo, output);
+  
+   bits = bits_processed (output);
+   
+   /*
+    *  Frame header information
+    */
+   {
+      const int rice_k = 8;     /* parameter of Rice Code */
+
+      write_rice_code (wfa->states, rice_k, output);      
+      write_rice_code (c->mt->frame_type, rice_k, output); 
+      write_rice_code (c->mt->number, rice_k, output);     
+   }
+   
+   OUTPUT_BYTE_ALIGN (output);
+
+   debug_message ("frame-header: %5d bits.", bits_processed (output) - bits);
+
+   if (c->tiling->exponent)     /* write tiling permutation */
+   {
+      put_bit (output, 1);
+      write_tiling (c->tiling, output);
+   }
+   else
+      put_bit (output, 0);
+
+   OUTPUT_BYTE_ALIGN (output);
+
+   write_tree (wfa, output);
+
+   if (c->options.prediction)       /* write nondeterministic approx. */
+   {
+      put_bit (output, 1); 
+      write_nd (wfa, output);
+   }
+   else
+      put_bit (output, 0);
+
+   if (c->mt->frame_type != I_FRAME)    /* write motion compensation info */
+      write_mc (c->mt->frame_type, wfa, output);
+   
+   edges = write_matrices (c->options.normal_domains,
+               c->options.delta_domains, wfa, output);
+
+   if (edges)               /* found at least one approximation */
+      write_weights (edges, wfa, output);
+
+   debug_message ("--------------------------------------"
+          "--------------------------------------");
+}
+
+void
+write_header (const wfa_info_t *wi, bitfile_t *output)
+/*
+ *  Write the header information describing the type of 'wfa'
+ *  to stream 'output'.
+ *
+ *  No return value.
+ */
+{
+   const unsigned rice_k = 8;       /* parameter of Rice Code */
+   unsigned   bits   = bits_processed (output);
+   const char *text;            /* next character to write */
+
+   /*
+    *  Write magic number and name of initial basis
+    */
+   for (text = FIASCO_MAGIC; *text; text++)
+      put_bits (output, *text, 8);
+   put_bits (output, '\n', 8);
+   for (text = wi->basis_name; *text; text++)
+      put_bits (output, *text, 8);
+   put_bits (output, *text, 8);
+   
+   write_rice_code (FIASCO_BINFILE_RELEASE, rice_k, output);
+
+   write_rice_code (HEADER_TITLE, rice_k, output);
+   for (text = wi->title;
+    text && *text && text - wi->title < MAXSTRLEN - 2;
+    text++)
+      put_bits (output, *text, 8);
+   put_bits (output, 0, 8);
+   
+   write_rice_code (HEADER_COMMENT, rice_k, output);
+   for (text = wi->comment;
+    text && *text && text - wi->comment < MAXSTRLEN - 2;
+    text++)
+      put_bits (output, *text, 8);
+   put_bits (output, 0, 8);
+   
+   write_rice_code (HEADER_END, rice_k, output);
+   
+   write_rice_code (wi->max_states, rice_k, output); 
+   put_bit (output, wi->color ? 1 : 0); 
+   write_rice_code (wi->width, rice_k, output);
+   write_rice_code (wi->height, rice_k, output);
+   if (wi->color)
+      write_rice_code (wi->chroma_max_states, rice_k, output); 
+   write_rice_code (wi->p_min_level, rice_k, output); 
+   write_rice_code (wi->p_max_level, rice_k, output); 
+   write_rice_code (wi->frames, rice_k, output);
+   write_rice_code (wi->smoothing, rice_k, output);
+
+   put_bits (output, wi->rpf->mantissa_bits - 2, 3);
+   put_bits (output, wi->rpf->range_e, 2);
+   if (wi->rpf->mantissa_bits != wi->dc_rpf->mantissa_bits ||
+       wi->rpf->range != wi->dc_rpf->range)
+   {
+      put_bit (output, YES);
+      put_bits (output, wi->dc_rpf->mantissa_bits - 2, 3);
+      put_bits (output, wi->dc_rpf->range_e, 2);
+   }
+   else
+      put_bit (output, NO);
+   if (wi->rpf->mantissa_bits != wi->d_rpf->mantissa_bits ||
+       wi->rpf->range != wi->d_rpf->range)
+   {
+      put_bit (output, YES);
+      put_bits (output, wi->d_rpf->mantissa_bits - 2, 3);
+      put_bits (output, wi->d_rpf->range_e, 2);
+   }
+   else
+      put_bit (output, NO);
+   if (wi->dc_rpf->mantissa_bits != wi->d_dc_rpf->mantissa_bits ||
+       wi->dc_rpf->range != wi->d_dc_rpf->range)
+   {
+      put_bit (output, YES);
+      put_bits (output, wi->d_dc_rpf->mantissa_bits - 2, 3);
+      put_bits (output, wi->d_dc_rpf->range_e, 2);
+   }
+   else
+      put_bit (output, NO);
+
+   if (wi->frames > 1)          /* motion compensation stuff */
+   {
+      write_rice_code (wi->fps, rice_k, output); 
+      write_rice_code (wi->search_range, rice_k, output); 
+      put_bit (output, wi->half_pixel ? 1 : 0); 
+      put_bit (output, wi->B_as_past_ref ? 1 : 0);
+   }
+
+   OUTPUT_BYTE_ALIGN (output);
+   debug_message ("header:         %d bits.", bits_processed (output) - bits);
+}
+
+/*****************************************************************************
+
+                private code
+  
+*****************************************************************************/
+
+static void
+write_tiling (const tiling_t *tiling, bitfile_t *output)
+/*
+ *  Write image tiling information given by 'tiling' to stream 'output'.
+ *
+ *  No return value.
+ */
+{
+   const unsigned rice_k = 8;       /* parameter of Rice Code */
+   unsigned       bits   = bits_processed (output);
+   
+   write_rice_code (tiling->exponent, rice_k, output);
+   if (tiling->method == FIASCO_TILING_VARIANCE_ASC
+       || tiling->method == FIASCO_TILING_VARIANCE_DSC)
+   {
+      unsigned tile;            /* current image tile */
+
+      put_bit (output, 1);      
+      for (tile = 0; tile < 1U << tiling->exponent; tile++)
+     if (tiling->vorder [tile] != -1) /* image tile is visible */
+        put_bits (output, tiling->vorder [tile], tiling->exponent);
+   }
+   else
+   {
+      put_bit (output, 0);      
+      put_bit (output, tiling->method == FIASCO_TILING_SPIRAL_ASC);
+   }
+
+   debug_message ("tiling:        %4d bits.", bits_processed (output) - bits);
+}
diff --git a/converter/other/fiasco/output/write.h b/converter/other/fiasco/output/write.h
new file mode 100644
index 00000000..a3ede1f4
--- /dev/null
+++ b/converter/other/fiasco/output/write.h
@@ -0,0 +1,28 @@
+/*
+ *  write.h
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/15 17:27:30 $
+ *  $Author: hafner $
+ *  $Revision: 5.2 $
+ *  $State: Exp $
+ */
+
+#ifndef _WRITE_H
+#define _WRITE_H
+
+#include "cwfa.h"
+#include "bit-io.h"
+
+void
+write_next_wfa (const wfa_t *wfa, const coding_t *c, bitfile_t *output);
+void
+write_header (const wfa_info_t *wi, bitfile_t *output);
+
+#endif /* not _WRITE_H */
diff --git a/converter/other/fiasco/params.c b/converter/other/fiasco/params.c
new file mode 100644
index 00000000..3d0a0252
--- /dev/null
+++ b/converter/other/fiasco/params.c
@@ -0,0 +1,727 @@
+/*
+ *  params.c:		Parameter file and command line parsing
+ *
+ *  Written by:		Stefan Frank
+ *			Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/07/15 17:24:21 $
+ *  $Author: hafner $
+ *  $Revision: 5.2 $
+ *  $State: Exp $
+ */
+
+#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>			/* strtod() on SUN sparc */
+
+#include <stdlib.h>
+#include <string.h>
+ 
+#include <getopt.h>			/* system or ../lib */
+
+#include "nstring.h"
+
+#include "types.h"
+#include "macros.h"
+#include "bit-io.h"
+#include "misc.h"
+#include "fiasco.h"
+
+#include "binerror.h"
+
+#include "params.h"
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void
+read_parameter_file (param_t *params, FILE *file);
+static int
+get_parameter_index (const param_t *params, const char *search_string);
+static void
+set_parameter (param_t *parameter, const char *value);
+static void 
+usage (const param_t *params, const char *progname, const char *synopsis,
+       const char *comment, const char *non_opt_string,
+       bool_t show_all_options, const char *sys_file_name,
+       const char *usr_file_name);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+
+int
+parseargs (param_t *usr_params, 
+           int argc, char **argv, 
+           const char *synopsis,
+           const char *comment, 
+           const char *non_opt_string, 
+           const char *path,
+           const char *sys_file_name, 
+           const char *usr_file_name)
+/*
+ *  Perform the command line parsing.
+ *  List of allowed parameters is given by 'usr_params'.
+ *  Command line and number of parameters are given by 'argv' and 'argc'.
+ *  'synopsis' contains a brief description of the program and
+ *  'comment' may contain some additional advice.
+ *  Initialization order of parameters:
+ *	1.) Default values given by the param_t struct
+ *	2.) System parameter-file ('path'/'sys_file_name')
+ *	3.) User parameter-file ($HOME/'usr_file_name')
+ *	4.) Command line parameters
+ *	5.) Parameter-file forced by option -f (--config-file)
+ *
+ *  Return value:
+ *	index in ARGV of the first ARGV-element that is not an option.
+ *
+ *  Side effects:
+ *	the elements of ARGV are permuted
+ *      usr_params [].value is modified 
+ */
+{
+   extern int optind;			/* index in ARGV of the 1st element
+					   that is not an option */
+   bool_t     detailed_help = NO;	/* NO if all parameters can be modified
+					   with short options too */
+   unsigned   n1;			/* number of user parameters */
+   unsigned   n2;			/* number of system parameters */
+   bool_t     read_config_file = NO;	/* will override command line */
+   param_t    *params;			/* array of user and system params */
+   param_t    *sys_params;		/* array of system parameters */
+   param_t    detailed_sys_params [] =  /* detailed system parameters */
+   {
+      {"version", NULL, 'v', PFLAG, {0}, NULL,
+       "Print program version number, then exit."},
+      {"verbose", "NUM", 'V', PINT, {0}, "1",
+       "Set level of verbosity to `%s'."},
+      {"config", "FILE", 'f', PSTR, {0}, NULL,
+       "Load `%s' to initialize parameters."},
+      {"info", NULL, 'h', PFLAG, {0}, NULL,
+       "Print brief help, then exit."},
+      {"help", NULL, 'H', PFLAG, {0}, NULL,
+       "Print detailed help, then exit."},
+      {NULL, NULL, 0, PSTR, {0}, NULL, NULL }
+   };
+   param_t    short_sys_params [] =	/* short system parameters */
+   {
+      {"version", NULL, 'v', PFLAG, {0}, NULL,
+       "Print program version number, then exit."},
+      {"verbose", "NUM", 'V', PINT, {0}, "1",
+       "Set level of verbosity to `%s'."},
+      {"config", "FILE", 'f', PSTR, {0}, NULL,
+       "Load `%s' to initialize parameters."},
+      {"help", NULL, 'h', PFLAG, {0}, NULL,
+       "Print this help, then exit."},
+      {NULL, NULL, 0, PSTR, {0}, NULL, NULL }
+   };
+   char *sys_path;			/* path to system config file */
+
+   sys_path = calloc (strlen (path) + strlen (sys_file_name) + 2,
+		      sizeof (char));
+   if (!sys_path)
+      error ("Out of memory.");
+   sprintf (sys_path, "%s/%s", path, sys_file_name);
+
+   /*
+    *  Set parameters defaults
+    */
+   {
+       param_t *p;
+      
+       for (p = usr_params; p->name != NULL; p++)
+       {
+           set_parameter (p, p->default_value);
+           if (p->optchar == '\0')
+               detailed_help = YES;
+       }
+
+      sys_params = detailed_help ? detailed_sys_params : short_sys_params;
+      
+      for (p = sys_params; p->name != NULL; p++)
+          set_parameter (p, p->default_value);
+   }
+   /*
+    *  Append system command line option to user parameters
+    */
+   for (n1 = 0; usr_params [n1].name != NULL; n1++)
+      ;
+   for (n2 = 0; sys_params [n2].name != NULL; n2++)
+      ;
+   params = calloc (n1 + n2 + 1, sizeof (param_t));
+   if (!params)
+      error ("Out of memory.");
+
+   memcpy (params, usr_params, n1 * sizeof (param_t));
+   memcpy (params + n1, sys_params, (n2 + 1) * sizeof (param_t));
+   /*
+    *  Try to open the system resource file 'path'/'sys_file_name'
+    */
+   {
+      FILE *parameter_file = open_file (sys_path, NULL, READ_ACCESS);
+      if (parameter_file == NULL)
+/*
+	 warning ("No system resource file found.");
+*/ {}
+      else
+      {
+	 read_parameter_file (params, parameter_file);
+	 fclose (parameter_file);
+      }
+   }
+   /*
+    *  Try to read user resource file $HOME/'usr_file_name'
+    */
+   {
+      FILE *parameter_file = open_file (usr_file_name, "HOME", READ_ACCESS);
+      if (parameter_file != NULL)
+      {
+	 read_parameter_file (params, parameter_file);
+	 fclose (parameter_file);
+      }
+   }
+   /*
+    *  Parse command line options
+    */
+   {
+      extern char   *optarg;		/* argument of current option */
+      struct option *long_options;	/* array of long options */
+      int	     option_index = 0;
+      char	     optstr [MAXSTRLEN]; /* string containing the legitimate
+					    option characters */
+      int	     optchar;		/* found option character */
+
+      /*
+       *  Build short option string for getopt_long (). 
+       */
+      {
+	 param_t *p;			/* counter */
+	 char	 *ptr_optstr;		/* pointer to position in string */
+	 
+	 ptr_optstr = optstr;
+	 for (p = params; p->name != NULL; p++)
+	    if (p->optchar != '\0')
+	    {
+	       *ptr_optstr++ = p->optchar;
+	       if (p->type == POSTR)
+	       {
+		  *ptr_optstr++ = ':';
+		  *ptr_optstr++ = ':';
+	       }
+	       else if (p->type != PFLAG)
+		  *ptr_optstr++ = ':';
+	    }
+	 *ptr_optstr = '\0';
+      }
+      
+      /*
+       *  Build long option string for getopt_long (). 
+       */
+      {
+	 int i;
+	 
+	 long_options = calloc (n1 + n2 + 1, sizeof (struct option));
+	 if (!long_options)
+	    error ("Out of memory.");
+	 for (i = 0; params [i].name != NULL; i++)
+	 {
+	    long_options [i].name    = params [i].name;
+	    switch (params [i].type)
+	    {
+	       case PFLAG:
+		  long_options [i].has_arg = 0;
+		  break;
+	       case POSTR:
+		  long_options [i].has_arg = 2;
+		  break;
+	       case PINT:
+	       case PSTR:
+	       case PFLOAT:
+	       default:
+		  long_options [i].has_arg = 1;
+		  break;
+	    }
+	    long_options [i].has_arg = params [i].type != PFLAG;
+	    long_options [i].flag    = NULL;
+	    long_options [i].val     = 0;
+	 }
+      }
+      
+      /*
+       *  Parse comand line
+       */
+      while ((optchar = getopt_long (argc, argv, optstr, long_options,
+				     &option_index)) != EOF)
+      {
+	 int param_index = -1;
+	 
+	 switch (optchar)
+	 {
+	    case 0:
+	       param_index = option_index;
+	       break;
+	    case ':':
+	       if (detailed_help)
+		  fprintf (stderr,
+			   "Try `%s -h' or `%s --help' for "
+			   "more information.\n",
+			   argv [0], argv [0]);
+	       else
+		  fprintf (stderr, "Try `%s --help' for more information.\n",
+			   argv [0]);
+	       exit (2);
+	       break;
+	    case '?':
+	       if (detailed_help)
+		  fprintf (stderr,
+			   "Try `%s -h' or `%s --help' "
+			   "for more information.\n",
+			   argv [0], argv [0]);
+	       else
+		  fprintf (stderr, "Try `%s --help' for more information.\n",
+			   argv [0]);
+	       exit (2);
+	       break;
+	    default:
+	       {
+		  int i;
+		  
+		  for (i = 0; params [i].name != NULL; i++)
+		     if (params [i].optchar == optchar)
+		     {
+			param_index = i;
+			break;
+		     }
+	       }
+	 }
+	 /*
+	  *  Check for system options
+	  */
+	 if (param_index >= 0)
+	 {
+	    set_parameter (params + param_index, optarg ? optarg : "");
+	    if (streq (params [param_index].name, "help"))
+	       usage (params, argv [0], synopsis, comment, non_opt_string,
+		      YES, sys_path, usr_file_name);
+	    else if (streq (params [param_index].name, "info"))
+	       usage (params, argv [0], synopsis, comment, non_opt_string,
+		      NO, sys_path, usr_file_name);
+	    else if (streq (params [param_index].name, "version"))
+	    {
+	       fprintf (stderr, "%s " VERSION "\n", argv [0]);
+	       exit (2);
+	    }
+	    else if (streq (params [param_index].name, "verbose"))
+	       fiasco_set_verbosity (
+               * (fiasco_verbosity_e *) parameter_value (params,
+                                                         "verbose"));
+	    else if (streq (params [param_index].name, "config"))
+	       read_config_file = YES;
+	    param_index = -1;		/* clear index flag */
+	 }
+      }
+
+      free (long_options);
+   }
+   
+   /*
+    *  Read config-file if specified by option -f
+    */
+   if (read_config_file)
+   {
+      char *filename;
+
+      if ((filename = (char *) parameter_value (params, "config")) != NULL)
+      {
+	 FILE *parameter_file;		/* input file */
+	 
+	 warning ("Options set in file `%s' will override"
+		  " command line options.", filename);
+	 parameter_file = open_file (filename, NULL, READ_ACCESS);
+	 if (parameter_file != NULL)
+	 {
+	    read_parameter_file (params, parameter_file);
+	    fclose (parameter_file);
+	 }
+	 else
+	    file_error (filename);
+      }
+      else
+	 error ("Invalid config filename.");
+   }
+
+   memcpy (usr_params, params, n1 * sizeof (param_t)); /* fill user struct */
+   free (sys_path);
+   
+   return optind;
+}
+ 
+void *
+parameter_value (const param_t *params, const char *name)
+/*
+ *  Extract value of parameter 'name.' of the given parameters 'params'.
+ *
+ *  Return value:
+ *	value of given parameter
+ */
+{
+   int pind = get_parameter_index (params, name);
+
+   if (pind < 0)
+      error ("Invalid parameter `%s'.", name);
+
+   if (params [pind].type == PSTR || params [pind].type == POSTR)
+      return (void *) params [pind].value.s;
+      
+   return (void *) &(params [pind].value);
+}
+
+void
+ask_and_set (param_t *params, const char *name, const char *msg)
+/*
+ *  Ask user (print given message 'msg') for missing mandatory
+ *  parameter 'name' of the given parameters 'params'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'params ['name'].value' is changed
+ */
+{ 
+   char answer [MAXSTRLEN];
+   int  index = get_parameter_index (params, name);
+
+   if (index < 0)
+      error ("Invalid parameter %s.", name);
+
+   if (msg)
+      fprintf (stderr, "%s\n", msg);
+  
+   switch (params [index].type)
+   {
+      case PFLAG:			/* Unusual, at least. */
+	 warning ("Flags should be initialized and set on demand, "
+		  "not request");
+      case PINT:
+      case PSTR:
+      case POSTR:
+      case PFLOAT:
+	 scanf (MAXSTRLEN_SCANF, answer);
+	 set_parameter (&params [index], answer);
+	 break;
+      default:
+	 error ("Invalid parameter type for %s", name);
+   }
+} 
+
+void
+write_parameters (const param_t *params, FILE *output)
+/*
+ *  Write all parameter settings to 'output'.
+ *
+ *  No return value.
+ */
+{
+   int pind;
+
+   if (!params || !output)
+      error ("Parameters must be not NULL.");
+
+   for (pind = 0; params [pind].name != NULL; pind++)
+   {
+      fprintf (output, "# %s = ", params [pind].name);
+      switch (params [pind].type)
+      {
+	 case PFLAG:
+	    fprintf (output, "%s\n", params [pind].value.b ? "TRUE" : "FALSE");
+	    break;
+	 case PINT:
+	    fprintf (output, "%d\n", params [pind].value.i);
+	    break;
+	 case PFLOAT:
+	    fprintf (output, "%.4f\n", (double) params [pind].value.f);
+	    break;
+	 case PSTR:
+	 case POSTR:
+	    fprintf (output, "%s\n", params [pind].value.s);
+	    break;
+	 default:
+	    error ("Invalid type %d for parameter %s",
+		   params [pind].type, params [pind].name);
+      }
+   }
+   fputc ('\n', output);
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void
+set_parameter (param_t *parameter, const char *value)
+/*
+ *  Set value of 'parameter' to 'value'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'parameter.value' is changed accordingly
+ */
+{
+   assert (parameter);
+   
+   switch (parameter->type)
+   {
+      case PFLAG:
+	 if (value != NULL && *value != '\0')
+	 {
+	    if (strcaseeq (value, "TRUE"))
+	       parameter->value.b = YES;
+	    else if (strcaseeq (value, "FALSE"))
+	       parameter->value.b = NO;
+	    else if (strcaseeq (value, "YES"))
+	       parameter->value.b = YES;
+	    else if (strcaseeq (value, "NO"))
+	       parameter->value.b = NO;
+	    else
+	    {
+	       long int	data;
+	       char	*endptr;
+	    
+	       data = strtol (value, &endptr, 0);
+	       if (*endptr != '\0' || endptr == value)
+		  warning ("Invalid value `%s' converted to %d",
+			   value, (int) data);
+	       parameter->value.b = data ? YES : NO;
+	    }
+	 }
+	 else
+	    parameter->value.b = !parameter->value.b;
+	 break;
+      case PINT:
+	 {
+	    long int  data;
+	    char     *endptr;
+	    
+	    data = strtol (value, &endptr, 0);
+	    if (*endptr != '\0' || endptr == value)
+	       warning ("Invalid value `%s' converted to %d",
+			value, (int) data);
+	    parameter->value.i = data;
+	 }
+	 break;
+      case PFLOAT:
+	 {
+	    double	data;
+	    char	*endptr;
+	    
+	    data = strtod (value, &endptr);
+	    if (*endptr != '\0' || endptr == value)
+	       warning ("Invalid value `%s' converted to %f",
+			value, (double) data);
+	    parameter->value.f = data;
+	 }
+	 break;
+      case PSTR:
+      case POSTR:
+	 parameter->value.s = value ? strdup (value) : NULL;
+	 break;
+      default:				
+	 error ("Invalid parameter type for %s", parameter->name);
+   }
+}
+
+static int
+get_parameter_index (const param_t *params, const char *search_string)
+/*
+ *  Search for parameter with name 'search_string' in parameter struct.
+ *
+ *  Return value:
+ *	index of parameter or -1 if no matching parameter has been found
+ */
+{
+   int n;
+   int index = -1;
+
+   assert (params && search_string);
+
+   for (n = 0; params [n].name != NULL; n++)
+      if (strcaseeq (params [n].name, search_string))
+      {
+	 index = n;
+	 break;
+      }
+
+   return index;
+}
+
+static void
+read_parameter_file (param_t *params, FILE *file)
+/*
+ *  Read parameter settings from 'file'.
+ *
+ *  No return value.
+ *
+ *  Side effects:
+ *	'params [].value' are changed if specified in 'file'
+ */
+{
+   char buffer [MAXSTRLEN];
+   int  n = 0;
+
+   assert (params && file);
+
+   while (fgets (buffer, MAXSTRLEN, file) != NULL)
+   {
+      char *b;				/* temporary variable */
+      char *name;			/* parameter name */
+      char *value;			/* parameter value */
+      int   pind;			/* current argument number */
+      
+      b = strchr (buffer, '#');
+      if (b != NULL)			/* Strip comments. */
+	 *b = '\0';
+
+      b = strchr (buffer, '=');
+      if (b == NULL)			/* Strip lines that contain no '=' */
+	 continue;
+      *b = '\0';			/* Replace '=' by string terminator */
+
+      /*
+       *  Extract value of parameter
+       */
+      for (value = b + 1; ISSPACE (*value); value++) 
+	 ;				/* Delete leading spaces */
+
+      for (b = value + strlen (value) - 1; b >= value && ISSPACE (*b); b--)
+	 *b = '\0';			/* Delete trailing spaces. */
+
+      /*
+       *  Extract parameter name
+       */
+      for (name = buffer; ISSPACE (*name); name++) 
+	 ;				/* Delete leading spaces */
+
+      for (b = name + strlen (name) - 1; b >= name && ISSPACE (*b); b--)
+	 *b = '\0';			/* Delete trailing spaces. */
+
+      pind = get_parameter_index (params, name);
+      if (pind >= 0)
+	 set_parameter (&params [pind], value);
+      
+      n++;
+   }
+}   
+
+static void 
+usage (const param_t *params, const char *progname, const char *synopsis,
+       const char *comment, const char *non_opt_string,
+       bool_t show_all_options, const char *sys_file_name,
+       const char *usr_file_name)
+/*
+ *  Generates and prints command line description from param_t struct 'params'.
+ *  'progname' is the name of the excecutable, 'synopsis' a short program
+ *  description, and 'comment' some more advice.
+ *  If flag 'show_all_options' is set then print also options that are not
+ *  associated with a short option character.
+ *  'sys_file_name' and 'usr_file_name' are filenames to parameter files.
+ *
+ *  No return value.
+ */
+{
+   int	  i;
+   size_t width = 0;
+   
+   fprintf (stderr, "Usage: %s [OPTION]...%s\n", progname,
+	    non_opt_string ? non_opt_string : " ");
+   if (synopsis != NULL)
+      fprintf (stderr, synopsis);
+   fprintf (stderr, "\n\n");
+   fprintf (stderr, "Mandatory or optional arguments to long options "
+	    "are mandatory or optional\nfor short options too. "
+	    "Default values are surrounded by {}.\n");
+   for (i = 0; params [i].name != NULL; i++)
+      if (params [i].optchar != '\0' || show_all_options)
+      {
+	 if (params [i].type == POSTR)
+	    width = max (width, (strlen (params [i].name)
+				 + strlen (params [i].argument_name) + 2));
+	 else if (params [i].type != PFLAG)
+	    width = max (width, (strlen (params [i].name)
+				 + strlen (params [i].argument_name)));
+	 else
+	    width = max (width, (strlen (params [i].name)) - 1);
+      }
+   
+   for (i = 0; params [i].name != NULL; i++)
+      if (params [i].optchar != '\0' || show_all_options)
+      {
+	 if (params [i].optchar != '\0')
+	    fprintf (stderr, "  -%c, --", params [i].optchar);
+	 else
+	    fprintf (stderr, "      --");
+	 
+	 if (params [i].type == POSTR)
+	    fprintf (stderr, "%s=[%s]%-*s  ", params [i].name,
+		     params [i].argument_name,
+		     max (0, (width - 2 - strlen (params [i].name)
+			   - strlen (params [i].argument_name))), "");
+	 else if (params [i].type != PFLAG)
+	    fprintf (stderr, "%s=%-*s  ", params [i].name,
+		  width - strlen (params [i].name),
+		  params [i].argument_name);
+	 else
+	    fprintf (stderr, "%-*s  ", width + 1, params [i].name);
+
+	 fprintf (stderr, params [i].use, params [i].argument_name);
+	 
+	 switch (params [i].type)
+	 {
+	    case PFLAG:
+	       break;
+	    case PINT:
+	       fprintf (stderr, "{%d}", params [i].value.i);
+	       break;
+	    case PFLOAT:
+	       fprintf (stderr, "{%.2f}", (double) params [i].value.f);
+	       break;
+	    case PSTR:
+	    case POSTR:
+	       if (params [i].value.s)
+		  fprintf (stderr, "{%s}", params [i].value.s);
+	       break;
+	    default:
+	       error ("type %d for %s invalid",
+		      params [i].type, params [i].name);
+	 }
+	 fprintf (stderr, "\n");
+      }
+   fprintf (stderr, "\n");
+   fprintf (stderr, "Parameter initialization order:\n");
+   fprintf (stderr,
+	    "1.) %s\n2.) $HOME/%s\t 3.) command line\t 4.) --config=file",
+	    sys_file_name, usr_file_name);
+   fprintf (stderr, "\n\n");
+   if (comment != NULL)
+      fprintf (stderr, "%s\n", comment);
+
+   exit (1);
+}
+
diff --git a/converter/other/fiasco/params.h b/converter/other/fiasco/params.h
new file mode 100644
index 00000000..810a9ff0
--- /dev/null
+++ b/converter/other/fiasco/params.h
@@ -0,0 +1,61 @@
+/*
+ *  params.h
+ *
+ *  Written by:     Stefan Frank
+ *          Ullrich Hafner
+ *      
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+
+/*
+ *  $Date: 2000/06/14 20:51:17 $
+ *  $Author: hafner $
+ *  $Revision: 5.1 $
+ *  $State: Exp $
+ */
+
+#ifndef PARAMS_H
+#define PARAMS_H
+
+#include <stdio.h>
+
+typedef union pdata_t           /* Allow for different */
+{                   /* parameter types. */
+    int    b;
+    int    i;
+    float  f;
+    char  *s;
+} pdata_t;
+
+typedef enum {PFLAG = 1, PINT, PFLOAT, PSTR, POSTR} param_e;
+
+typedef struct param_t
+{
+    const char  *name;           /* Parameter name */
+    const char  *argument_name;      /* Argument name */
+    char         optchar;            /* Corresponding command line switch */
+    param_e      type;           /* Parameter type */
+    pdata_t      value;          /* Parameter value */
+    const char  *default_value;      /* Parameters default value */
+    const char  *use;            /* One line usage. Must contain %s,
+                                    which will be replaced by 'name'. */
+} param_t;
+
+int
+parseargs (param_t *usr_params, 
+           int argc, char **argv, 
+           const char *synopsis,
+           const char *comment, 
+           const char *non_opt_string, 
+           const char *path,
+           const char *sys_file_name, 
+           const char *usr_file_name);
+void
+write_parameters (const param_t *params, FILE *output);
+void
+ask_and_set (param_t *params, const char *name, const char *msg);
+void *
+parameter_value (const param_t *params, const char *name);
+
+#endif /* not PARAMS_H */
diff --git a/converter/other/fiasco/pnmtofiasco.c b/converter/other/fiasco/pnmtofiasco.c
new file mode 100644
index 00000000..2218256d
--- /dev/null
+++ b/converter/other/fiasco/pnmtofiasco.c
@@ -0,0 +1,411 @@
+/*
+ *  cwfa.c:		FIASCO coder
+ *
+ *  Written by:		Ullrich Hafner
+ *		
+ *  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+ *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+ */
+ 
+/*
+ *  $Date: 2000/10/28 17:39:29 $
+ *  $Author: hafner $
+ *  $Revision: 5.4 $
+ *  $State: Exp $
+ */
+
+#include "config.h"
+#include "pnm.h"
+
+#if STDC_HEADERS
+#	include <stdlib.h>
+#	include <string.h>
+#else /* not STDC_HEADERS */
+#	if HAVE_STRING_H
+#		include <string.h>
+#	else /* not HAVE_STRING_H */
+#		include <strings.h>
+#	endif /* not HAVE_STRING_H */
+#endif /* not STDC_HEADERS */
+
+#include "types.h"
+#include "macros.h"
+
+#include "binerror.h"
+#include "misc.h"
+#include "params.h"
+#include "fiasco.h"
+
+/*****************************************************************************
+
+			     local variables
+  
+*****************************************************************************/
+
+static param_t params [] =
+{
+  /*
+   *  Options for standard user
+   */
+  {"image-name", "FILE", 'i', PSTR, {0}, NULL,
+   "Compress raw PPM/PGM image(s) `%s'."},
+  {"output-name", "FILE", 'o', PSTR, {0}, "-",
+   "Write automaton to `%s' (`-' means stdout)."},
+  {"quality", "REAL", 'q', PFLOAT, {0}, "20.0",
+   "Set quality of compression to `%s'."},
+  {"title", "NAME", 't', PSTR, {0}, "",
+   "Set title of FIASCO stream to `%s'."},
+  {"comment", "NAME", 'c', PSTR, {0}, "",
+   "Set comment of FIASCO stream to `%s'."},
+  {"chroma-qfactor", "REAL", '\0', PFLOAT, {0}, "2",
+   "Decrease chroma band quality `%s' times."},
+  {"basis-name", "FILE", '\0', PSTR, {0}, "small.fco",
+   "Preload basis `%s' into FIASCO."},
+  {"optimize", "NUM", 'z', PINT, {0}, "0",
+   "Set optimization level to `%s'."},
+  {"dictionary-size", "NUM", '\0', PINT, {0}, "10000",
+   "Set max# size of dictionary to `%s'."},
+  {"chroma-dictionary", "NUM", '\0', PINT, {0}, "40",
+   "Set max# size of chroma dictionary to `%s'.."},
+  {"min-level", "NUM", '\0', PINT, {0}, "6",
+   "Start prediction on block level `%s'."},
+  {"max-level", "NUM", '\0', PINT, {0}, "10",
+   "Stop prediction on block level `%s'."},
+  {"tiling-exponent", "NUM", '\0', PINT, {0}, "4",
+   "Set exponent of image permutation to `%s'."},
+  {"tiling-method", "NAME", '\0', PSTR, {0}, "desc-variance",
+   "Set type of permutation to `%s'."},
+  {"rpf-range", "REAL", '\0', PFLOAT, {0}, "1.5",
+   "Set quantization range to `%s'."},
+  {"rpf-mantissa", "NUM", '\0', PINT, {0}, "3",
+   "Set quantization mantissa to `%s' bits."},
+  {"dc-rpf-range", "REAL", '\0', PFLOAT, {0}, "1",
+   "Set quant. range (DC part) to `%s'."},
+  {"dc-rpf-mantissa", "NUM", '\0', PINT, {0}, "5",
+   "Set quant. mantissa (DC part) to `%s' bits."},
+  {"pattern", "NAME", '\0', PSTR, {0}, "ippppppppp",
+   "Set frame type sequence to `%s'."},
+  {"fps", "NUM", '\0', PINT, {0}, "25",
+   "Set display rate to `%s' frames per second."},
+  {"half-pixel", NULL, '\0', PFLAG, {0}, "FALSE",
+   "Use half-pixel precision for mc."},
+  {"cross-B-search", NULL, '\0', PFLAG, {0}, "FALSE",
+   "Use cross-B-search for interpolated mc."},
+  {"B-as-past-ref", NULL, '\0', PFLAG, {0}, "FALSE",
+   "Use B-frames as reference images." },
+  {"prediction", NULL, '\0', PFLAG, {0}, "FALSE",
+   "Use additional predictive coding."},
+  {"progress-meter", "NUM", '\0', PINT, {0}, "2",
+   "Set type of progress meter to `%s'."},
+  {"smooth", "NUM", '\0', PINT, {0}, "70",
+   "Smooth image(s) by factor `%s' (0-100)"},
+#if 0
+  /*
+   *  Options currently not activated (maybe in future versions of FIASCO)
+   */
+  {"min-level", "NUM", 'm', PINT, {0}, "4",
+   "Start compression on block level `%s'."},
+  {"max-level", "NUM", 'M', PINT, {0}, "12",
+   "Stop compression on block level `%s'."},
+  {"max-elements", "NUM", 'N', PINT, {0}, "8",
+   "Set max# of elements in an approx. to `%s'." },
+  {"domain-pool", "NAME", '\0', PSTR, {0}, "rle",
+   "Set domain pool of r-lc to `%s'."},
+  {"coeff", "NAME", '\0', PSTR, {0}, "adaptive",
+   "Set coefficients model to `%s'."},
+  /*  DELTA APPROXIATION  */
+  {"d-domain-pool", "NAME", '\0', PSTR, {0}, "rle",
+   "Set domain pool of d-lc to `%s'."},
+  {"d-coeff", "NAME", '\0', PSTR, {0}, "adaptive",
+   "Set d coefficients model to `%s'."},
+  {"d-range", "REAL", '\0', PFLOAT, {0}, "1.5",
+   "Set range of RPF for delta lc to `%s'."},
+  {"d-mantissa", "NUM", '\0', PINT, {0}, "3",
+   "Set #m-bits of RPF for delta lc to `%s'."},
+  {"d-dc-range", "REAL", '\0', PFLOAT, {0}, "1",
+   "Set DC range of RPF of delta lc to `%s'."},
+  {"d-dc-mantissa", "NUM", '\0', PINT, {0}, "5",
+   "Set #m-bits of delta RPF for DC domain to `%s'."},
+  /*  ADVANCED  */
+  {"images-level", "NUM", '\0', PINT, {0}, "5",
+   "Compute state images up to level `%s'."},
+  {"delta-domains", NULL, '\0', PFLAG, {0}, "FALSE",
+   "Use delta domains every time."},
+  {"normal-domains", NULL, '\0', PFLAG, {0}, "FALSE",
+   "Use normal domains every time."},
+  /*  VIDEO COMPRESSION  */
+  {"smooth", "REAL", 's', PFLOAT, {0}, "1.0",
+   "Smooth frames by factor `%s' (0.5 - 1.0)"},
+  {"reference-frame", "FILE", '\0', PSTR, {0}, NULL,
+   "Use PPM/PGM image `%s' as reference frame."},
+#endif  
+  {NULL, NULL, 0, PSTR, {0}, NULL, NULL }
+};
+
+/*****************************************************************************
+
+				prototypes
+  
+*****************************************************************************/
+
+static void 
+checkargs (int argc, char **argv, char const ***image_template,
+	   char **wfa_name, float *quality, fiasco_c_options_t **options);
+
+/*****************************************************************************
+
+				public code
+  
+*****************************************************************************/
+ 
+int 
+main (int argc, char **argv)
+{
+   char const 	      **image_template;	/* template for input image files */
+   char	       	       *wfa_name;	/* filename of output WFA */
+   float	      	quality;	/* approximation quality */
+   fiasco_c_options_t  *options;	/* additional coder options */
+   
+   pnm_init(&argc, argv);
+   
+   init_error_handling (argv [0]);
+
+   checkargs (argc, argv, &image_template, &wfa_name, &quality, &options);
+
+   if (fiasco_coder (image_template, wfa_name, quality, options))
+      return 0;
+   else
+   {
+      fprintf (stderr, fiasco_get_error_message ());
+      fprintf (stderr, "\n");
+      return 1;
+   }
+}
+
+/*****************************************************************************
+
+				private code
+  
+*****************************************************************************/
+
+static void 
+checkargs (int argc, char **argv, char const ***image_template,
+	   char **wfa_name, float *quality, fiasco_c_options_t **options)
+/*
+ *  Check validness of command line parameters and of the parameter files.
+ *
+ *  Return value:
+ *	1 on success
+ *	0 otherwise
+ *  
+ *
+ *  Side effects:
+ *	'image_template', 'wfa_name', 'quality' and 'options' are set.
+ */
+{
+   int	 optind;			/* last processed commandline param */
+   char	*image_name;			/* filename given by option '-i' */
+   int	 i;				/* counter */
+   
+   optind = parseargs (params, argc, argv,
+		       "Compress raw PPM/PGM image FILEs to a FIASCO file.",
+		       "With no image FILE, or if FILE is -, "
+		       "read standard input.\n"
+		       "FILE must be either a filename"
+		       " or an image template of the form:\n"
+		       "`prefix[start-end{+,-}step]suffix'\n"
+		       "e.g., img0[12-01-1].pgm is substituted by"
+		       " img012.pgm ... img001.pgm\n\n"
+		       "Environment:\n"
+		       "FIASCO_DATA   Search and save path for FIASCO files. "
+		       "Default: ./\n"
+		       "FIASCO_IMAGES Search path for image files. "
+		       "Default: ./", " [FILE]...",
+		       FIASCO_SHARE, "system.fiascorc", ".fiascorc");
+
+   /*
+    *  Default options ...
+    */
+   image_name = (char *) parameter_value (params, "image-name"); 
+   *wfa_name  = (char *) parameter_value (params, "output-name");
+   for (;;)
+   {
+      *quality = * (float *) parameter_value (params, "quality");
+      if (*quality > 100)
+	 fprintf (stderr, "Typical range of quality: (0,100].\n"
+		  "Expect some trouble on slow machines.\n");
+      if (*quality > 0)
+	 break;
+      ask_and_set (params, "quality",
+		   "Please enter coding quality 'q' ('q' > 0): ");
+   }
+   
+   if (optind < argc)			/* Additional command line param */
+   {
+      if (image_name)
+	 error ("Multiple image_template arguments."
+		"\nOption -i %s already specified!", image_name);
+
+      *image_template = calloc (argc - optind + 1, sizeof (char *));
+      if (!*image_template)
+	 error ("Out of memory.");
+      for (i = 0; optind < argc; i++, optind++)
+	 (*image_template) [i] = argv [optind];
+      (*image_template) [i] = NULL;
+   }
+   else					/* option -i image_name */
+   {
+      *image_template = calloc (2, sizeof (char *));
+      if (!*image_template)
+	 error ("Out of memory.");
+      (*image_template) [0] = image_name;
+      (*image_template) [1] = NULL;
+   }
+   /*
+    *  Additional options ... (have to be set with the fiasco_set_... methods)
+    */
+   {
+      *options = fiasco_c_options_new ();
+      
+      {
+	 char *pattern = (char *) parameter_value (params, "pattern");
+
+	 if (!fiasco_c_options_set_frame_pattern (*options, pattern))
+	    error (fiasco_get_error_message ());
+      }
+
+      {
+	 char *basis = (char *) parameter_value (params, "basis-name");
+	 
+	 if (!fiasco_c_options_set_basisfile (*options, basis))
+	    error (fiasco_get_error_message ());
+      }
+
+      {
+	 int   n = * (int *) parameter_value (params, "chroma-dictionary");
+	 float q = * (float *) parameter_value (params, "chroma-qfactor");
+      
+	 if (!fiasco_c_options_set_chroma_quality (*options, q, max (0, n)))
+	    error (fiasco_get_error_message ());
+      }
+      
+      {
+	 int n = *((int *) parameter_value (params, "smooth"));
+	 
+	 if (!fiasco_c_options_set_smoothing (*options, max (0, n)))
+	    error (fiasco_get_error_message ());
+      }
+      
+      {
+          int n = * (int *) parameter_value (params, "progress-meter");
+          fiasco_progress_e type = (n < 0) ? 
+              FIASCO_PROGRESS_NONE : (fiasco_progress_e) n;
+      
+          if (!fiasco_c_options_set_progress_meter (*options, type))
+              error (fiasco_get_error_message ());
+      }
+      
+      {
+	 char *t = (char *) parameter_value (params, "title");
+	 
+	 if (strlen (t) > 0 && !fiasco_c_options_set_title (*options, t))
+	    error (fiasco_get_error_message ());
+      }
+      
+      {
+	 char *c = (char *) parameter_value (params, "comment");
+
+	 if (strlen (c) > 0 && !fiasco_c_options_set_comment (*options, c))
+	    error (fiasco_get_error_message ());
+      }
+      
+      {
+	 fiasco_tiling_e method = FIASCO_TILING_VARIANCE_DSC;
+	 int   e  = * (int *) parameter_value (params, "tiling-exponent");
+	 char *m  = (char *) parameter_value (params, "tiling-method");
+
+	 if (strcaseeq (m, "desc-variance"))
+	    method = FIASCO_TILING_VARIANCE_DSC;
+	 else if (strcaseeq (m, "asc-variance"))
+	    method = FIASCO_TILING_VARIANCE_ASC;
+	 else if (strcaseeq (m, "asc-spiral"))
+	    method = FIASCO_TILING_SPIRAL_ASC;
+	 else if (strcaseeq (m, "dsc-spiral"))
+	    method = FIASCO_TILING_SPIRAL_DSC;
+	 else
+	    error (_("Invalid tiling method `%s' specified."), m);
+
+	 if (!fiasco_c_options_set_tiling (*options, method, max (0, e)))
+	    error (fiasco_get_error_message ());
+      }
+      
+      {
+	 int M/*  = * (int *) parameter_value (params, "max-level") */;
+	 int m/*  = * (int *) parameter_value (params, "min-level") */;
+	 int N/*  = * (int *) parameter_value (params, "max-elements") */;
+	 int D = * (int *) parameter_value (params, "dictionary-size");
+	 int o = * (int *) parameter_value (params, "optimize");
+
+	 if (o <= 0)
+	 {
+	    o = 0;
+	    M = 10;
+	    m = 6;
+	    N = 3;
+	 }
+	 else
+	 {
+	    o -= 1;
+	    M = 12;
+	    m = 4;
+	    N = 5;
+	 }
+	 
+	 if (!fiasco_c_options_set_optimizations (*options, m, M, N,
+						  max (0, D), o))
+	    error (fiasco_get_error_message ());
+      }
+      {
+	 int M = * (int *) parameter_value (params, "max-level");
+	 int m = * (int *) parameter_value (params, "min-level");
+	 int p = * (int *) parameter_value (params, "prediction");
+	 
+	 if (!fiasco_c_options_set_prediction (*options,
+					       p, max (0, m), max (0, M)))
+	    error (fiasco_get_error_message ());
+      }
+      {
+	 float r    = * (float *) parameter_value (params, "rpf-range");
+	 float dc_r = * (float *) parameter_value (params, "dc-rpf-range");
+	 int   m    = * (int *)   parameter_value (params, "rpf-mantissa");
+	 int   dc_m = * (int *)   parameter_value (params, "dc-rpf-mantissa");
+	 fiasco_rpf_range_e range, dc_range;
+	 
+	 if (r < 1)
+	    range = FIASCO_RPF_RANGE_0_75;
+	 else if (r < 1.5)
+	    range = FIASCO_RPF_RANGE_1_00;
+	 else if (r < 2.0)
+	    range = FIASCO_RPF_RANGE_1_50;
+	 else
+	    range = FIASCO_RPF_RANGE_2_00;
+	    
+	 if (dc_r < 1)
+	    dc_range = FIASCO_RPF_RANGE_0_75;
+	 else if (dc_r < 1.5)
+	    dc_range = FIASCO_RPF_RANGE_1_00;
+	 else if (dc_r < 2.0)
+	    dc_range = FIASCO_RPF_RANGE_1_50;
+	 else
+	    dc_range = FIASCO_RPF_RANGE_2_00;
+	    
+	 if (!fiasco_c_options_set_quantization (*options,
+						 max (0, m), range,
+						 max (0, dc_m), dc_range))
+	    error (fiasco_get_error_message ());
+      }
+
+      if (fiasco_get_verbosity () == FIASCO_ULTIMATE_VERBOSITY)
+	 write_parameters (params, stderr);
+   }
+}	
diff --git a/converter/other/fiasco/system.fiascorc b/converter/other/fiasco/system.fiascorc
new file mode 100644
index 00000000..86ff2da2
--- /dev/null
+++ b/converter/other/fiasco/system.fiascorc
@@ -0,0 +1,120 @@
+#
+#  system.wfarc:	Resource file WFA coder
+# 
+#  Written by:		Ullrich Hafner
+#		
+#  This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec)
+#  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de>
+
+#
+#  $Date: 2000/06/25 16:38:01 $
+#  $Author: hafner $
+#  $Revision: 5.2 $
+#  $State: Exp $
+
+#
+# Options for FIASCO coder `cfiasco':
+#
+
+# Initial basis to start with
+# small.fco:  domains 1, x, y
+# medium.fco: domains 1, x, y and 129 additional images
+# large.fco: domains 1, x, y and 226 additional images
+basis-name = small.fco
+
+# Limit the number of elements in the dictionary by `dictionary-size' 
+# The smaller the value is the faster the coder runs and the worse
+# the image quality will be.  
+dictionary-size = 10000
+
+# Optimization level
+#  0: standard approximation method, process blocks of level [6, 10],
+#     use up to 3 dictionary vectors
+#  1: standard approximation method, process blocks of level [4, 12],
+#     use up to 5 dictionary vectors
+#  2: significantly increases the approximation quality,
+#     running time is twice as high as with the standard method
+#  3: hardly increases the approximation quality of method 2, 
+#     running time is twice as high as with method 21
+#     (this method just remains for completeness)
+optimize = 0
+
+# Approximation quality (typical range = [1-100]) 
+quality = 20.0                    
+
+# For compression of chroma bands the dictionary can be reduced to
+# the best #`chroma-dictionary' elements.
+# Furthermore, the quality of the approximation is decreased
+# 'chroma-qfactor' times.
+chroma-dictionary = 40
+chroma-qfactor    = 2
+
+# Verbosity level
+# 0 no debug output
+# 1 some verbosity and statistics of the output size
+# 2 lots of debug information and log-files are written
+verbose = 1
+
+# Set exponent and method of image tiling
+# 0   image is processed in normal bintree order
+# >0  image is subdivided into 2^`tiling-exponent' tiles. 
+# Set type of image tiling
+# asc-variance  Tiles with large variances are processed first
+# desc-variance Tiles with small variances are processed first
+# asc-spiral    Tiles are process in spiral order starting in the middle
+# desc-spiral   Tiles are process in spiral order starting at the border
+tiling-exponent = 4
+tiling-method   = desc-variance
+
+# Quantization parameters define the accuracy of coefficients quantization.
+# DC coefficients (of the constant dictionary vector f(x,y) = 1) are quantized
+# to values of the interval [-`dc-rpf-range', `dc-rpf-range'] using
+# #`dc-rpf-mantissa' bits. All other quantized coefficients are quantized in
+# an analogous way using the parameters `rpf-range' and `rpf-mantissa'.
+rpf-mantissa    = 3
+rpf-range       = 1.5
+dc-rpf-mantissa = 5
+dc-rpf-range    = 1
+
+# Search for prediction (coarse approximation or motion compensation)
+# on all levels between minlevel and maxlevel
+min-level = 6
+max-level = 10
+
+# Set various parameters used for video compensation.
+# 'fps' defines the frame rate which should be
+# used when the video is decoded. This value has no effect during coding,
+# it is just passed to the FIASCO output file.
+# If 'half-pixel' is set then half pixel precise
+# motion compensated prediction is used.
+# If 'cross-B-search' is set then the fast Cross-B-Search algorithm is
+# used to determine the motion vectors of interpolated prediction. Otherwise
+# exhaustive search (in the given search range) is used.
+# If 'B-as-past-ref' is set then B frames are allowed to be used
+# for B frame predicion.
+fps            = 25
+half-pixel     = NO
+cross-B-search = NO
+B-as-past-ref  = NO
+
+# Set `pattern' of input frames.
+# `pattern' has to be a sequence of the following
+# characters (case insensitive):
+# 'i' intra frame
+# 'p' predicted frame
+# 'b' bidirectional predicted frame
+# E.g. pattern = 'IBBPBBPBB'
+#
+# When coding video frames the prediction type of input frame N is determined
+# by reading `pattern' [N] (`pattern' is periodically extended).
+
+pattern = ippppppppp
+
+#
+# Options for FIASCO decoder `dfiasco':
+#
+
+double  = NO
+reduced = NO
+panel   = NO
+enlarge = 0