about summary refs log tree commit diff
path: root/converter/other/fiasco/codec/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/fiasco/codec/control.c')
-rw-r--r--converter/other/fiasco/codec/control.c276
1 files changed, 276 insertions, 0 deletions
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));
+    
+}