about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--converter/other/fiasco/codec/approx.c898
-rw-r--r--converter/other/fiasco/codec/decoder.c2
-rw-r--r--converter/other/fiasco/fiascotopnm.c2
-rw-r--r--converter/other/fiasco/lib/dither.c12
-rw-r--r--converter/other/fiasco/lib/error.c179
5 files changed, 524 insertions, 569 deletions
diff --git a/converter/other/fiasco/codec/approx.c b/converter/other/fiasco/codec/approx.c
index 5072fae3..6c5e9fc5 100644
--- a/converter/other/fiasco/codec/approx.c
+++ b/converter/other/fiasco/codec/approx.c
@@ -1,8 +1,8 @@
 /*
- *  approx.c:		Approximation of range images with matching pursuit
+ *  approx.c:       Approximation of range images with matching pursuit
  *
- *  Written by:		Ullrich Hafner
- *		
+ *  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>
  */
@@ -34,7 +34,7 @@
 
 /*****************************************************************************
 
-			     local variables
+                 local variables
   
 *****************************************************************************/
 
@@ -52,227 +52,205 @@ typedef struct mp
 
 /*****************************************************************************
 
-			     prototypes
+                 prototypes
   
 *****************************************************************************/
 
 static void
 orthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm,
-	       const word_t *domain_blocks, const coding_t *c);
+           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);
+          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
+                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;
+                   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;
+
+    /*
+     *  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;
       
-      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;
+        tmp_mp = mp;  /* initial value */
+
+        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 */ 
+            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) {
+        mp_t tmp_mp;
+        int  iteration;
+
+        tmp_mp = mp;  /* initial value */
+        iteration = -1;  /* initial value */
       
-      do
-      {
-	 int i;
+        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 */
+                    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) {
+        mp_t tmp_mp;
+        int  iteration;
+
+        tmp_mp = mp;  /* initial value */
+        iteration = -1;  /* initial value */
+
+        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;
-	    }
-	 }
+            ++iteration;
+            tmp_mp.exclude[iteration] = NO_EDGE;
+     
+            for (i = 0; isdomain (tmp_mp.indices [i]); ++i) {
+                rpf_t * const 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;
+            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 */
+                    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;
+        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) {
+                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;
+            }
+        }
+        mp.indices [new_index] = NO_EDGE;
+        mp.into    [new_index] = NO_EDGE;
+
+        /*
+         *  Update of probability models
+         */
+        {
+            word_t * const 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);
+        }
       
-      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;
-   }
+        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;
+    return mp.costs;
 }
 
+
+
 /*****************************************************************************
 
-			     local variables
+                 local variables
   
 *****************************************************************************/
 
@@ -310,15 +288,15 @@ static bool_t used [MAXSTATES];
 
 /*****************************************************************************
 
-				private code
+                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)
+          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
@@ -339,38 +317,38 @@ matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
  *  No return value.
  *
  *  Side effects:
- *	vectors, factors, rate, distortion and costs are stored in 'mp'
+ *  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);
+   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);
+                      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);
+      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 */
+     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);
+     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;
+     used [domain] = YES;
    }
 
    /*
@@ -389,15 +367,15 @@ matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
       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;
+             + 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);
+                     y_state, wfa, domain_pool->model);
    mp->costs        = (mp->matrix_bits + mp->weights_bits
-		       + additional_bits) * price + mp->err;
+               + additional_bits) * price + mp->err;
 
    n = 0;
    do 
@@ -406,7 +384,7 @@ matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
        *  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}
+       *  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.
@@ -415,235 +393,235 @@ matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
       
       real_t min_matrix_bits  = 0;
       real_t min_weights_bits = 0;
-      real_t min_error 	      = 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 (!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 (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++;
-      }	
+     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;
+           + 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)
+           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
@@ -655,8 +633,8 @@ orthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm,
  *  No return value.
  *
  *  Side effects:
- *	The remainder values (numerator and denominator) of
- *	all 'domain_blocks' are updated. 
+ *  The remainder values (numerator and denominator) of
+ *  all 'domain_blocks' are updated. 
  */
 {
    unsigned domain;
@@ -676,25 +654,25 @@ orthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm,
    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;
+     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/decoder.c b/converter/other/fiasco/codec/decoder.c
index 26284596..72dd4e98 100644
--- a/converter/other/fiasco/codec/decoder.c
+++ b/converter/other/fiasco/codec/decoder.c
@@ -603,7 +603,6 @@ decode_range (unsigned range_state, unsigned range_label, unsigned range_level,
  *  '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 */
@@ -613,7 +612,6 @@ decode_range (unsigned range_state, unsigned range_label, unsigned range_level,
 
    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);
diff --git a/converter/other/fiasco/fiascotopnm.c b/converter/other/fiasco/fiascotopnm.c
index dfba2256..0de50aed 100644
--- a/converter/other/fiasco/fiascotopnm.c
+++ b/converter/other/fiasco/fiascotopnm.c
@@ -361,6 +361,8 @@ video_decoder (const char *wfa_name, const char *image_name, bool_t panel,
                 while (prg_timer (&fps_timer, STOP) < frame_time) /* wait */
                     ;
             }
+#else
+            if (frame_time) {/* defeat compiler warning */}
 #endif /* not X_DISPLAY_MISSING */   
         }
         free (filename);
diff --git a/converter/other/fiasco/lib/dither.c b/converter/other/fiasco/lib/dither.c
index accd9dd6..e8a3c449 100644
--- a/converter/other/fiasco/lib/dither.c
+++ b/converter/other/fiasco/lib/dither.c
@@ -713,15 +713,11 @@ display_24_bit_bgr (const struct fiasco_renderer *this, unsigned char *ximage,
       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];
@@ -1044,9 +1040,7 @@ display_24_bit_bgr (const struct fiasco_renderer *this, unsigned char *ximage,
    {
       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];
 
@@ -1164,15 +1158,11 @@ display_24_bit_rgb (const struct fiasco_renderer *this, unsigned char *ximage,
       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];
@@ -1495,9 +1485,7 @@ display_24_bit_rgb (const struct fiasco_renderer *this, unsigned char *ximage,
    {
       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];
 
diff --git a/converter/other/fiasco/lib/error.c b/converter/other/fiasco/lib/error.c
index ee3afe1f..e67e1461 100644
--- a/converter/other/fiasco/lib/error.c
+++ b/converter/other/fiasco/lib/error.c
@@ -64,118 +64,107 @@ jmp_buf env;
 *****************************************************************************/
 
 void
-set_error (const char *format, ...)
-/*
- *  Set error text to given string.
- */
-{
-   va_list     args;
-   unsigned    len = 0;
-   const char *str = format;
+set_error(const char *format, ...) {
+/*----------------------------------------------------------------------------
+  Set error text to given string.
+-----------------------------------------------------------------------------*/
+    va_list      args;
+    unsigned     len;
+    const char * str;
+
+    len = 0;  /* initial value */
+    str = format;  /* initial value */
+
+    VA_START (args, format);
+
+    len = strlen (format);
+    while ((str = strchr (str, '%'))) {
+        ++str;
+        if (*str == 's') {
+            char * const vstring = va_arg (args, char *);
+            len += strlen(vstring);
+        } else if (*str == 'd') {
+            va_arg (args, int);
+            len += 10;
+        } else if (*str == 'c') {
+            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));
    
-   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);
+    vsprintf(error_message, format, args);
 
-   VA_START (args, format);
+    va_end(args);
+}
 
-   if (error_message)
-      Free (error_message);
-   error_message = Calloc (len, sizeof (char));
-   
-   vsprintf (error_message, format, args);
 
-   va_end (args);
-}
 
 void
-error (const char *format, ...)
-/*
- *  Set error text to given string.
- */
-{
-   va_list     args;
-   unsigned    len = 0;
-   const char *str = format;
+error(const char *format, ...) {
+/*----------------------------------------------------------------------------
+  Set error text to given string.
+  -----------------------------------------------------------------------------*/
+    va_list      args;
+    unsigned     len;
+    const char * str;
    
-   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
-      {
+    len = 0; /* initial value */
+    str = &format[0];  /* initial value */
+
+    VA_START (args, format);
+
+    len = strlen (format);
+    while ((str = strchr (str, '%'))) {
+        ++str;
+        if (*str == 's') {
+            char * const vstring = va_arg (args, char *);
+            len += strlen(vstring);
+        } else if (*str == 'd') {
+            va_arg (args, int);
+            len += 10;
+        } else if (*str == 'c') {
+            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 */
-      };
+            longjmp(env, 1);
+#else
+            exit(1);
+#endif
+        };
       
-      str++;
-   }
-   va_end(args);
+        ++str;
+    }
+    va_end(args);
 
-   VA_START (args, format);
+    VA_START(args, format);
 
-   if (error_message)
-      Free (error_message);
-   error_message = Calloc (len, sizeof (char));
+    if (error_message)
+        Free(error_message);
+    error_message = Calloc(len, sizeof (char));
    
-   vsprintf (error_message, format, args);
+    vsprintf(error_message, format, args);
 
-   va_end (args);
+    va_end(args);
    
 #if HAVE_SETJMP_H
-   longjmp (env, 1);
-#else /* not HAVE_SETJMP_H */
-   exit (1);
-#endif /* HAVE_SETJMP_H */
+    longjmp(env, 1);
+#else
+    exit(1);
+#endif
 }
 
+
+
 const char *
 fiasco_get_error_message (void)
 /*