Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
	    }
	 }
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}