Blame converter/other/fiasco/codec/prediction.c

Packit 78deda
/*
Packit 78deda
 *  prediction.c:	Range image prediction with MC or ND	
Packit 78deda
 *
Packit 78deda
 *  Written by:		Ullrich Hafner
Packit 78deda
 *			Michael Unger
Packit 78deda
 *		
Packit 78deda
 *  This file is part of FIASCO (Fractal Image And Sequence COdec)
Packit 78deda
 *  Copyright (C) 1994-2000 Ullrich Hafner
Packit 78deda
 */
Packit 78deda
Packit 78deda
/*
Packit 78deda
 *  $Date: 2000/06/14 20:50:51 $
Packit 78deda
 *  $Author: hafner $
Packit 78deda
 *  $Revision: 5.1 $
Packit 78deda
 *  $State: Exp $
Packit 78deda
 */
Packit 78deda
Packit 78deda
#include "config.h"
Packit 78deda
Packit 78deda
#include <string.h>
Packit 78deda
Packit 78deda
#include "types.h"
Packit 78deda
#include "macros.h"
Packit 78deda
#include "error.h"
Packit 78deda
Packit 78deda
#include "cwfa.h"
Packit 78deda
#include "ip.h"
Packit 78deda
#include "control.h"
Packit 78deda
#include "misc.h"
Packit 78deda
#include "subdivide.h"
Packit 78deda
#include "bintree.h"
Packit 78deda
#include "domain-pool.h"
Packit 78deda
#include "approx.h"
Packit 78deda
#include "wfalib.h"
Packit 78deda
#include "mwfa.h"
Packit 78deda
#include "prediction.h"
Packit 78deda
Packit 78deda
#include "decoder.h"
Packit 78deda
Packit 78deda
Packit 78deda
/*****************************************************************************
Packit 78deda
Packit 78deda
			     local variables
Packit 78deda
  
Packit 78deda
*****************************************************************************/
Packit 78deda
Packit 78deda
typedef struct state_data
Packit 78deda
{
Packit 78deda
   real_t final_distribution;
Packit 78deda
   byte_t level_of_state;
Packit 78deda
   byte_t domain_type;
Packit 78deda
Packit 78deda
   real_t *images_of_state;
Packit 78deda
   real_t *inner_products;
Packit 78deda
   real_t *ip_states_state [MAXLEVEL];
Packit 78deda
Packit 78deda
   word_t tree [MAXLABELS];
Packit 78deda
   mv_t	  mv_tree [MAXLABELS];
Packit 78deda
   word_t y_state [MAXLABELS];
Packit 78deda
   byte_t y_column [MAXLABELS];
Packit 78deda
   byte_t prediction [MAXLABELS];
Packit 78deda
Packit 78deda
   u_word_t x [MAXLABELS];
Packit 78deda
   u_word_t y [MAXLABELS];
Packit 78deda
Packit 78deda
   real_t weight [MAXLABELS][MAXEDGES + 1];
Packit 78deda
   word_t int_weight [MAXLABELS][MAXEDGES + 1];
Packit 78deda
   word_t into [MAXLABELS][MAXEDGES + 1];
Packit 78deda
} state_data_t;
Packit 78deda
Packit 78deda
/*****************************************************************************
Packit 78deda
Packit 78deda
				prototypes
Packit 78deda
  
Packit 78deda
*****************************************************************************/
Packit 78deda
Packit 78deda
static real_t
Packit 78deda
nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
Packit 78deda
	       range_t *range, wfa_t *wfa, coding_t *c);
Packit 78deda
static real_t
Packit 78deda
mc_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
Packit 78deda
	       range_t *range, wfa_t *wfa, coding_t *c);
Packit 78deda
static state_data_t *
Packit 78deda
store_state_data (unsigned from, unsigned to, unsigned max_level,
Packit 78deda
		  wfa_t *wfa, coding_t *c);
Packit 78deda
static void
Packit 78deda
restore_state_data (unsigned from, unsigned to, unsigned max_level,
Packit 78deda
		    state_data_t *data, wfa_t *wfa, coding_t *c);
Packit 78deda
Packit 78deda
/*****************************************************************************
Packit 78deda
Packit 78deda
				public code
Packit 78deda
  
Packit 78deda
*****************************************************************************/
Packit 78deda
 
Packit 78deda
real_t
Packit 78deda
predict_range (real_t max_costs, real_t price, range_t *range, wfa_t *wfa,
Packit 78deda
	       coding_t *c, unsigned band, int y_state, unsigned states,
Packit 78deda
	       const tree_t *tree_model, const tree_t *p_tree_model,
Packit 78deda
	       const void *domain_model, const void *d_domain_model,
Packit 78deda
	       const void *coeff_model, const void *d_coeff_model)
Packit 78deda
{
Packit 78deda
   unsigned	 state;		     	/* counter */
Packit 78deda
   void		*rec_domain_model;   	/* domain model after recursion */
Packit 78deda
   void		*rec_d_domain_model; 	/* p domain model after recursion */
Packit 78deda
   void		*rec_coeff_model;    	/* coeff model after recursion */
Packit 78deda
   void		*rec_d_coeff_model;  	/* d coeff model after recursion */
Packit 78deda
   tree_t	 rec_tree_model;	/* tree_model after '' */
Packit 78deda
   tree_t	 rec_p_tree_model;    	/* p_tree_model after '' */
Packit 78deda
   unsigned	 rec_states;	     	/* wfa->states after '' */
Packit 78deda
   real_t	*rec_pixels;	     	/* c->pixels after '' */
Packit 78deda
   state_data_t	*rec_state_data;     	/* state_data struct after '' */
Packit 78deda
   real_t	 costs;		     	/* current approximation costs */
Packit 78deda
   unsigned	 level;		     	/* counter */
Packit 78deda
   state_data_t	*sd;		     	/* pointer to state_data field */
Packit 78deda
Packit 78deda
   /*
Packit 78deda
    *  Store WFA data from state 'lc_states' to 'wfa->states' - 1 and
Packit 78deda
    *  current state of probability models.
Packit 78deda
    */
Packit 78deda
   rec_domain_model   = c->domain_pool->model;
Packit 78deda
   rec_d_domain_model = c->d_domain_pool->model;
Packit 78deda
   rec_coeff_model    = c->coeff->model;
Packit 78deda
   rec_d_coeff_model  = c->d_coeff->model;
Packit 78deda
   rec_tree_model     = c->tree;
Packit 78deda
   rec_p_tree_model   = c->p_tree;
Packit 78deda
   rec_states         = wfa->states;	
Packit 78deda
   rec_pixels         = c->pixels;
Packit 78deda
   rec_state_data     = store_state_data (states, rec_states - 1,
Packit 78deda
					  c->options.lc_max_level, wfa, c);
Packit 78deda
   
Packit 78deda
   /*
Packit 78deda
    *  Restore probability models to the state before the recursive subdivision
Packit 78deda
    *  has been started.
Packit 78deda
    */
Packit 78deda
   wfa->states             = states;
Packit 78deda
   c->tree                 = *tree_model;
Packit 78deda
   c->p_tree               = *p_tree_model;
Packit 78deda
   c->domain_pool->model   = c->domain_pool->model_duplicate (domain_model);
Packit 78deda
   c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model);
Packit 78deda
   c->coeff->model   	   = c->coeff->model_duplicate (c->coeff, coeff_model);
Packit 78deda
   c->d_coeff->model   	   = c->d_coeff->model_duplicate (c->d_coeff,
Packit 78deda
							  d_coeff_model);
Packit 78deda
   
Packit 78deda
   if (c->mt->frame_type == I_FRAME)
Packit 78deda
      costs = nd_prediction (max_costs, price, band, y_state, range, wfa, c); 
Packit 78deda
   else
Packit 78deda
      costs = mc_prediction (max_costs, price, band, y_state, range, wfa, c);
Packit 78deda
   
Packit 78deda
   c->pixels = rec_pixels;
Packit 78deda
   
Packit 78deda
   if (costs < MAXCOSTS)
Packit 78deda
   {
Packit 78deda
      /*
Packit 78deda
       *  Free the memory used by the state_data struct
Packit 78deda
       */
Packit 78deda
      for (state = states; state < rec_states; state++)
Packit 78deda
      {
Packit 78deda
	 sd = &rec_state_data [state - states];
Packit 78deda
	 for (level = c->options.images_level + 1;
Packit 78deda
	      level <= c->options.lc_max_level; level++)
Packit 78deda
	    if (sd->ip_states_state [level] != NULL)
Packit 78deda
	       Free (sd->ip_states_state [level]);
Packit 78deda
	 if (sd->images_of_state != NULL)
Packit 78deda
	    Free (sd->images_of_state);
Packit 78deda
	 if (sd->inner_products != NULL)
Packit 78deda
	    Free (sd->inner_products);
Packit 78deda
      }
Packit 78deda
      if (states < rec_states)
Packit 78deda
	 Free (rec_state_data);
Packit 78deda
      c->domain_pool->model_free (rec_domain_model);
Packit 78deda
      c->d_domain_pool->model_free (rec_d_domain_model);
Packit 78deda
      c->coeff->model_free (rec_coeff_model);
Packit 78deda
      c->d_coeff->model_free (rec_d_coeff_model);
Packit 78deda
Packit 78deda
      costs = (range->tree_bits + range->matrix_bits + range->weights_bits
Packit 78deda
	       + range->mv_tree_bits + range->mv_coord_bits
Packit 78deda
	       + range->nd_tree_bits + range->nd_weights_bits) * price
Packit 78deda
	      + range->err;
Packit 78deda
   }
Packit 78deda
   else
Packit 78deda
   {
Packit 78deda
      /*
Packit 78deda
       *  Restore WFA to state before function was called
Packit 78deda
       */
Packit 78deda
      c->domain_pool->model_free (c->domain_pool->model);
Packit 78deda
      c->d_domain_pool->model_free (c->d_domain_pool->model);
Packit 78deda
      c->coeff->model_free (c->coeff->model);
Packit 78deda
      c->d_coeff->model_free (c->d_coeff->model);
Packit 78deda
      
Packit 78deda
      c->domain_pool->model   = rec_domain_model;
Packit 78deda
      c->d_domain_pool->model = rec_d_domain_model;
Packit 78deda
      c->coeff->model         = rec_coeff_model;
Packit 78deda
      c->d_coeff->model       = rec_d_coeff_model;
Packit 78deda
      c->tree                 = rec_tree_model;
Packit 78deda
      c->p_tree               = rec_p_tree_model;
Packit 78deda
      
Packit 78deda
      range->prediction = NO;
Packit 78deda
      
Packit 78deda
      if (wfa->states != states)
Packit 78deda
	 remove_states (states, wfa);
Packit 78deda
      restore_state_data (states, rec_states - 1, c->options.lc_max_level,
Packit 78deda
			  rec_state_data, wfa, c);
Packit 78deda
      costs = MAXCOSTS;
Packit 78deda
   }
Packit 78deda
 
Packit 78deda
   return costs;
Packit 78deda
} 
Packit 78deda
Packit 78deda
void
Packit 78deda
clear_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)
Packit 78deda
/*
Packit 78deda
 *  Clear norms arrays.
Packit 78deda
 *
Packit 78deda
 *  No return value.
Packit 78deda
 */
Packit 78deda
{
Packit 78deda
   unsigned  range_size = wi->half_pixel
Packit 78deda
			  ? square (wi->search_range)
Packit 78deda
			  : square (2 * wi->search_range);
Packit 78deda
Packit 78deda
   if (level > wi->p_min_level)
Packit 78deda
   {
Packit 78deda
      memset (mt->mc_forward_norms [level], 0, range_size * sizeof(real_t));
Packit 78deda
      memset (mt->mc_backward_norms [level], 0, range_size * sizeof(real_t));
Packit 78deda
   }
Packit 78deda
}
Packit 78deda
Packit 78deda
void
Packit 78deda
update_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)
Packit 78deda
/*
Packit 78deda
 *  Norms table of levels larger than the bottom level are computed
Packit 78deda
 *  by summing up previously calculated displacement costs of lower levels.
Packit 78deda
 *
Packit 78deda
 *  No return value.
Packit 78deda
 */
Packit 78deda
{
Packit 78deda
   unsigned  range_size = wi->half_pixel
Packit 78deda
			  ? square (wi->search_range)
Packit 78deda
			  : square (2 * wi->search_range);
Packit 78deda
   
Packit 78deda
   if (level > wi->p_min_level)
Packit 78deda
   {
Packit 78deda
      unsigned index;			/* index of motion vector */
Packit 78deda
      
Packit 78deda
      for (index = 0; index < range_size; index++)
Packit 78deda
	 mt->mc_forward_norms [level][index]
Packit 78deda
	    += mt->mc_forward_norms [level - 1][index];
Packit 78deda
      if (mt->frame_type == B_FRAME)
Packit 78deda
	 for (index = 0; index < range_size; index++)
Packit 78deda
	    mt->mc_backward_norms [level][index]
Packit 78deda
	       += mt->mc_backward_norms [level - 1][index];
Packit 78deda
   }
Packit 78deda
}
Packit 78deda
Packit 78deda
/*****************************************************************************
Packit 78deda
Packit 78deda
				private code
Packit 78deda
  
Packit 78deda
*****************************************************************************/
Packit 78deda
Packit 78deda
static real_t
Packit 78deda
mc_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
Packit 78deda
	       range_t *range, wfa_t *wfa, coding_t *c)
Packit 78deda
{
Packit 78deda
   real_t    costs;		   	/* current approximation costs */
Packit 78deda
   range_t   prange = *range;
Packit 78deda
   unsigned  width  = width_of_level (range->level);
Packit 78deda
   unsigned  height = height_of_level (range->level);
Packit 78deda
   word_t   *mcpe   = Calloc (width * height, sizeof (word_t));
Packit 78deda
Packit 78deda
   /*
Packit 78deda
    *  If we are at the bottom level of the mc tree:
Packit 78deda
    *  Fill in the norms table
Packit 78deda
    */
Packit 78deda
   if (prange.level == wfa->wfainfo->p_min_level) 
Packit 78deda
      fill_norms_table (prange.x, prange.y, prange.level, wfa->wfainfo, c->mt);
Packit 78deda
   /*
Packit 78deda
    *  Predict 'range' with motion compensation according to frame type.
Packit 78deda
    *  MCPE is returned in 'c->mcpe'
Packit 78deda
    */
Packit 78deda
   if (c->mt->frame_type == P_FRAME)
Packit 78deda
      find_P_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt);
Packit 78deda
   else
Packit 78deda
      find_B_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt);
Packit 78deda
   
Packit 78deda
   costs = (prange.mv_tree_bits + prange.mv_coord_bits) * price;
Packit 78deda
   
Packit 78deda
   if (costs < max_costs)		/* motion vector not too expensive */
Packit 78deda
   {
Packit 78deda
      unsigned  last_state;		/* last WFA state before recursion */
Packit 78deda
      real_t   *ipi [MAXSTATES];	/* inner products pointers */
Packit 78deda
      unsigned  state;
Packit 78deda
      real_t  	mvt, mvc;
Packit 78deda
      
Packit 78deda
      c->pixels = Calloc (width * height, sizeof (real_t));
Packit 78deda
      cut_to_bintree (c->pixels, mcpe, width, height, 0, 0, width, height);
Packit 78deda
   
Packit 78deda
      /*
Packit 78deda
       *  Approximate MCPE recursively.
Packit 78deda
       */
Packit 78deda
      last_state = wfa->states - 1;
Packit 78deda
      for (state = 0; state <= last_state; state++)
Packit 78deda
	 if (need_image (state, wfa))
Packit 78deda
	 {
Packit 78deda
	    ipi [state] = c->ip_images_state[state];
Packit 78deda
	    c->ip_images_state[state]
Packit 78deda
	       = Calloc (size_of_tree (c->products_level), sizeof (real_t));
Packit 78deda
	 }
Packit 78deda
Packit 78deda
      mvc = prange.mv_coord_bits;
Packit 78deda
      mvt = prange.mv_tree_bits;
Packit 78deda
      
Packit 78deda
      prange.image           = 0;
Packit 78deda
      prange.address         = 0;
Packit 78deda
      prange.tree_bits       = 0;
Packit 78deda
      prange.matrix_bits     = 0;
Packit 78deda
      prange.weights_bits    = 0;
Packit 78deda
      prange.mv_coord_bits   = 0;
Packit 78deda
      prange.mv_tree_bits    = 0;
Packit 78deda
      prange.nd_weights_bits = 0;
Packit 78deda
      prange.nd_tree_bits    = 0;
Packit 78deda
Packit 78deda
      compute_ip_images_state (prange.image, prange.address, prange.level,
Packit 78deda
			       1, 0, wfa, c);
Packit 78deda
      costs += subdivide (max_costs - costs, band, y_state, &prange,
Packit 78deda
			  wfa, c, NO, YES);
Packit 78deda
Packit 78deda
      if (costs < max_costs)		/* use motion compensation */
Packit 78deda
      {
Packit 78deda
	 unsigned img, adr;		/* temp. values */
Packit 78deda
	 
Packit 78deda
	 img                  = range->image;
Packit 78deda
	 adr                  = range->address;
Packit 78deda
	 *range               = prange;
Packit 78deda
	 range->image         = img;
Packit 78deda
	 range->address       = adr;
Packit 78deda
	 range->mv_coord_bits = mvc;
Packit 78deda
	 range->mv_tree_bits  = mvt;
Packit 78deda
	 range->prediction    = YES;
Packit 78deda
Packit 78deda
	 for (state = last_state + 1; state < wfa->states; state++)
Packit 78deda
	    if (need_image (state, wfa))
Packit 78deda
	       memset (c->ip_images_state [state], 0,
Packit 78deda
		       size_of_tree (c->products_level) * sizeof (real_t));
Packit 78deda
Packit 78deda
	 costs = (range->tree_bits + range->matrix_bits + range->weights_bits
Packit 78deda
		  + range->mv_tree_bits + range->mv_coord_bits
Packit 78deda
		  + range->nd_tree_bits + range->nd_weights_bits) * price
Packit 78deda
		 + range->err;
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
	 costs = MAXCOSTS;
Packit 78deda
Packit 78deda
      for (state = 0; state <= last_state; state++)
Packit 78deda
	 if (need_image (state, wfa))
Packit 78deda
	 {
Packit 78deda
	    Free (c->ip_images_state[state]);
Packit 78deda
	    c->ip_images_state[state] = ipi [state];
Packit 78deda
	 }
Packit 78deda
      Free (c->pixels);
Packit 78deda
   }
Packit 78deda
   else
Packit 78deda
      costs = MAXCOSTS;
Packit 78deda
   
Packit 78deda
   Free (mcpe);
Packit 78deda
Packit 78deda
   return costs;
Packit 78deda
}
Packit 78deda
Packit 78deda
static real_t
Packit 78deda
nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
Packit 78deda
	       range_t *range, wfa_t *wfa, coding_t *c)
Packit 78deda
{
Packit 78deda
   real_t  costs;			/* current approximation costs */
Packit 78deda
   range_t lrange = *range;
Packit 78deda
   
Packit 78deda
   /*
Packit 78deda
    *  Predict 'range' with DC component approximation
Packit 78deda
    */
Packit 78deda
   {
Packit 78deda
      real_t x = get_ip_image_state (range->image, range->address,
Packit 78deda
				     range->level, 0, c);
Packit 78deda
      real_t y = get_ip_state_state (0, 0, range->level, c);
Packit 78deda
      real_t w = btor (rtob (x / y, c->coeff->dc_rpf), c->coeff->dc_rpf);
Packit 78deda
      word_t s [2] = {0, -1};
Packit 78deda
Packit 78deda
      lrange.into [0] 	     = 0;
Packit 78deda
      lrange.into [1] 	     = NO_EDGE;
Packit 78deda
      lrange.weight [0]      = w;
Packit 78deda
      lrange.mv_coord_bits   = 0;
Packit 78deda
      lrange.mv_tree_bits    = 0;
Packit 78deda
      lrange.nd_tree_bits    = tree_bits (LEAF, lrange.level, &c->p_tree);
Packit 78deda
      lrange.nd_weights_bits = 0;
Packit 78deda
      lrange.tree_bits       = 0;
Packit 78deda
      lrange.matrix_bits     = 0;
Packit 78deda
      lrange.weights_bits    = c->coeff->bits (&w, s, range->level, c->coeff);
Packit 78deda
   }
Packit 78deda
   costs = price * (lrange.weights_bits + lrange.nd_tree_bits);
Packit 78deda
   
Packit 78deda
   /*
Packit 78deda
    *  Recursive aproximation of difference image
Packit 78deda
    */
Packit 78deda
   if (costs < max_costs)		
Packit 78deda
   {
Packit 78deda
      unsigned  state;
Packit 78deda
      range_t  	rrange;			/* range: recursive subdivision */
Packit 78deda
      unsigned  last_state;		/* last WFA state before recursion */
Packit 78deda
      real_t   *ipi [MAXSTATES];	/* inner products pointers */
Packit 78deda
      unsigned 	width  = width_of_level (range->level);
Packit 78deda
      unsigned  height = height_of_level (range->level);
Packit 78deda
      real_t   *pixels;
Packit 78deda
Packit 78deda
      /*
Packit 78deda
       *  Generate difference image original - approximation
Packit 78deda
       */
Packit 78deda
      {
Packit 78deda
	 unsigned  n;
Packit 78deda
	 real_t *src, *dst;		/* pointers to image data */
Packit 78deda
	 real_t w = - lrange.weight [0] * c->images_of_state [0][0];
Packit 78deda
		     
Packit 78deda
	 src = c->pixels + range->address * size_of_level (range->level); 
Packit 78deda
	 dst = c->pixels = pixels = Calloc (width * height, sizeof (real_t));
Packit 78deda
Packit 78deda
	 for (n = width * height; n; n--)
Packit 78deda
	    *dst++ = *src++ + w;
Packit 78deda
      }
Packit 78deda
      
Packit 78deda
      /*
Packit 78deda
       *  Approximate difference recursively.
Packit 78deda
       */
Packit 78deda
      rrange                 = *range;
Packit 78deda
      rrange.tree_bits       = 0;
Packit 78deda
      rrange.matrix_bits     = 0;
Packit 78deda
      rrange.weights_bits    = 0;
Packit 78deda
      rrange.mv_coord_bits   = 0;
Packit 78deda
      rrange.mv_tree_bits    = 0;
Packit 78deda
      rrange.nd_tree_bits    = 0;
Packit 78deda
      rrange.nd_weights_bits = 0;
Packit 78deda
      rrange.image           = 0;
Packit 78deda
      rrange.address         = 0;
Packit 78deda
Packit 78deda
      last_state = wfa->states - 1;
Packit 78deda
      for (state = 0; state <= last_state; state++)
Packit 78deda
	 if (need_image (state, wfa))
Packit 78deda
	 {
Packit 78deda
	    ipi [state] = c->ip_images_state[state];
Packit 78deda
	    c->ip_images_state[state]
Packit 78deda
	       = Calloc (size_of_tree (c->products_level), sizeof (real_t));
Packit 78deda
	 }
Packit 78deda
      
Packit 78deda
      compute_ip_images_state (rrange.image, rrange.address, rrange.level,
Packit 78deda
			       1, 0, wfa, c);
Packit 78deda
      
Packit 78deda
      costs += subdivide (max_costs - costs, band, y_state, &rrange, wfa, c,
Packit 78deda
			  NO, YES);
Packit 78deda
      
Packit 78deda
      Free (pixels);
Packit 78deda
Packit 78deda
      if (costs < max_costs && ischild (rrange.tree)) /* use prediction */
Packit 78deda
      {
Packit 78deda
	 unsigned img, adr;
Packit 78deda
	 unsigned edge;
Packit 78deda
Packit 78deda
	 img                     = range->image;
Packit 78deda
	 adr                     = range->address;
Packit 78deda
	 *range                  = rrange;
Packit 78deda
	 range->image            = img;
Packit 78deda
	 range->address          = adr;
Packit 78deda
	 range->nd_tree_bits    += lrange.nd_tree_bits;
Packit 78deda
	 range->nd_weights_bits += lrange.weights_bits;
Packit 78deda
	 
Packit 78deda
	 for (edge = 0; isedge (lrange.into [edge]); edge++)
Packit 78deda
	 {
Packit 78deda
	    range->into [edge]   = lrange.into [edge];
Packit 78deda
	    range->weight [edge] = lrange.weight [edge];
Packit 78deda
	 }
Packit 78deda
	 range->into [edge] = NO_EDGE;
Packit 78deda
	 range->prediction  = edge;
Packit 78deda
Packit 78deda
	 for (state = last_state + 1; state < wfa->states; state++)
Packit 78deda
	    if (need_image (state, wfa))
Packit 78deda
	       memset (c->ip_images_state [state], 0,
Packit 78deda
		       size_of_tree (c->products_level) * sizeof (real_t));
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
	 costs = MAXCOSTS;
Packit 78deda
      
Packit 78deda
      for (state = 0; state <= last_state; state++)
Packit 78deda
	 if (need_image (state, wfa))
Packit 78deda
	 {
Packit 78deda
	    Free (c->ip_images_state [state]);
Packit 78deda
	    c->ip_images_state [state] = ipi [state];
Packit 78deda
	 }
Packit 78deda
   }
Packit 78deda
   else
Packit 78deda
      costs = MAXCOSTS;
Packit 78deda
Packit 78deda
   return costs;
Packit 78deda
}
Packit 78deda
Packit 78deda
static state_data_t *
Packit 78deda
store_state_data (unsigned from, unsigned to, unsigned max_level,
Packit 78deda
		  wfa_t *wfa, coding_t *c)
Packit 78deda
/*
Packit 78deda
 *  Save and remove all states starting from state 'from'.
Packit 78deda
 *
Packit 78deda
 *  Return value:
Packit 78deda
 *	pointer to array of state_data structs
Packit 78deda
 */
Packit 78deda
{
Packit 78deda
   state_data_t *data;			/* array of savestates */
Packit 78deda
   state_data_t *sd;			/* pointer to current savestates */
Packit 78deda
   unsigned	 state, label, level;
Packit 78deda
Packit 78deda
   if (to < from)
Packit 78deda
      return NULL;			/* nothing to do */
Packit 78deda
   
Packit 78deda
   data = Calloc (to - from + 1, sizeof (state_data_t));
Packit 78deda
   
Packit 78deda
   for (state = from; state <= to; state++)
Packit 78deda
   {
Packit 78deda
      sd = &data [state - from];
Packit 78deda
Packit 78deda
      sd->final_distribution = wfa->final_distribution [state];
Packit 78deda
      sd->level_of_state     = wfa->level_of_state [state];
Packit 78deda
      sd->domain_type        = wfa->domain_type [state];
Packit 78deda
      sd->images_of_state    = c->images_of_state [state];
Packit 78deda
      sd->inner_products     = c->ip_images_state [state];
Packit 78deda
      
Packit 78deda
      wfa->domain_type [state]   = 0;
Packit 78deda
      c->images_of_state [state] = NULL;
Packit 78deda
      c->ip_images_state [state] = NULL;
Packit 78deda
				   
Packit 78deda
      for (label = 0; label < MAXLABELS; label++) 
Packit 78deda
      {
Packit 78deda
	 sd->tree [label]     	= wfa->tree [state][label];
Packit 78deda
	 sd->y_state [label]  	= wfa->y_state [state][label];
Packit 78deda
	 sd->y_column [label] 	= wfa->y_column [state][label];
Packit 78deda
	 sd->mv_tree [label]  	= wfa->mv_tree [state][label];
Packit 78deda
	 sd->x [label]        	= wfa->x [state][label];
Packit 78deda
	 sd->y [label]        	= wfa->y [state][label];
Packit 78deda
	 sd->prediction [label] = wfa->prediction [state][label];
Packit 78deda
Packit 78deda
	 memcpy (sd->weight [label], wfa->weight [state][label], 
Packit 78deda
		 sizeof (real_t) * (MAXEDGES + 1));
Packit 78deda
	 memcpy (sd->int_weight [label], wfa->int_weight [state][label], 
Packit 78deda
		 sizeof (word_t) * (MAXEDGES + 1));
Packit 78deda
	 memcpy (sd->into [label], wfa->into [state][label], 
Packit 78deda
		 sizeof (word_t) * (MAXEDGES + 1));
Packit 78deda
Packit 78deda
	 wfa->into [state][label][0] = NO_EDGE;
Packit 78deda
	 wfa->tree [state][label]    = RANGE;
Packit 78deda
	 wfa->y_state [state][label] = RANGE;
Packit 78deda
      }
Packit 78deda
      for (level = c->options.images_level + 1; level <= max_level;
Packit 78deda
	   level++)
Packit 78deda
      {
Packit 78deda
	 sd->ip_states_state [level]       = c->ip_states_state [state][level];
Packit 78deda
	 c->ip_states_state [state][level] = NULL;
Packit 78deda
      }
Packit 78deda
   }
Packit 78deda
Packit 78deda
   return data;
Packit 78deda
}
Packit 78deda
Packit 78deda
static void
Packit 78deda
restore_state_data (unsigned from, unsigned to, unsigned max_level,
Packit 78deda
		    state_data_t *data, wfa_t *wfa, coding_t *c)
Packit 78deda
/*
Packit 78deda
 *  Restore all state data starting from state 'from'.
Packit 78deda
 *  
Packit 78deda
 *  No return value.
Packit 78deda
 */
Packit 78deda
{
Packit 78deda
   state_data_t *sd;			/* pointer to state_data item */
Packit 78deda
   unsigned	 state, label, level;
Packit 78deda
Packit 78deda
   if (to < from)
Packit 78deda
      return;				/* nothing to do */
Packit 78deda
   
Packit 78deda
   for (state = from; state <= to; state++)
Packit 78deda
   {
Packit 78deda
      sd = &data [state - from];
Packit 78deda
      
Packit 78deda
      wfa->final_distribution [state] = sd->final_distribution;
Packit 78deda
      wfa->level_of_state [state]     = sd->level_of_state;
Packit 78deda
      wfa->domain_type [state]        = sd->domain_type;
Packit 78deda
      
Packit 78deda
      if (c->images_of_state [state] != NULL)
Packit 78deda
	 Free (c->images_of_state [state]);
Packit 78deda
      c->images_of_state [state] = sd->images_of_state;
Packit 78deda
      if (c->ip_images_state [state] != NULL)
Packit 78deda
	 Free (c->ip_images_state [state]);
Packit 78deda
      c->ip_images_state [state] = sd->inner_products;
Packit 78deda
Packit 78deda
      for (label = 0; label < MAXLABELS; label++)
Packit 78deda
      {
Packit 78deda
	 wfa->tree [state][label]     	= sd->tree [label];
Packit 78deda
	 wfa->y_state [state][label]  	= sd->y_state [label];
Packit 78deda
	 wfa->y_column [state][label] 	= sd->y_column [label];
Packit 78deda
	 wfa->mv_tree [state][label]  	= sd->mv_tree [label];
Packit 78deda
	 wfa->x [state][label]        	= sd->x [label];
Packit 78deda
	 wfa->y [state][label]        	= sd->y [label];
Packit 78deda
	 wfa->prediction [state][label] = sd->prediction [label];
Packit 78deda
	 
Packit 78deda
	 memcpy (wfa->weight [state][label], sd->weight [label], 
Packit 78deda
		 sizeof(real_t) * (MAXEDGES + 1));
Packit 78deda
	 memcpy (wfa->int_weight [state][label], sd->int_weight [label], 
Packit 78deda
		 sizeof(word_t) * (MAXEDGES + 1));
Packit 78deda
	 memcpy (wfa->into [state][label], sd->into [label],  
Packit 78deda
		 sizeof(word_t) * (MAXEDGES + 1));
Packit 78deda
      }	 
Packit 78deda
      for (level = c->options.images_level + 1; level <= max_level;
Packit 78deda
	   level++)
Packit 78deda
      {
Packit 78deda
	 if (c->ip_states_state [state][level] != NULL)
Packit 78deda
	    Free (c->ip_states_state [state][level]);
Packit 78deda
	 c->ip_states_state [state][level] = sd->ip_states_state [level];
Packit 78deda
      }
Packit 78deda
   }
Packit 78deda
Packit 78deda
   Free (data);
Packit 78deda
   wfa->states = to + 1;
Packit 78deda
}