Esempio n. 1
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. 2
0
image_t *
decode_image (unsigned orig_width, unsigned orig_height, format_e format,
	      unsigned *dec_timer, const wfa_t *wfa)
/*
 *  Compute image which is represented by the given 'wfa'.
 *  'orig_width'x'orig_height' gives the resolution of the image at
 *  coding time. Use 4:2:0 subsampling or 4:4:4 'format' for color images.
 *  If 'dec_timer' is given, accumulate running time statistics. 
 *  
 *  Return value:
 *	pointer to decoded image
 *
 *  Side effects:
 *	'*dectimer' is changed if 'dectimer' != NULL.
 */
{
   unsigned   root_state [3];		/* root of bintree for each band */
   unsigned   width, height;		/* computed image size */
   image_t   *frame;			/* regenerated frame */
   word_t   **images;			/* pointer to array of pointers
					   to state images */
   u_word_t  *offsets;			/* pointer to array of state image
					   offsets */
   unsigned   max_level;		/* max. level of state with approx. */
   unsigned   state;
   clock_t    ptimer;

   prg_timer (&ptimer, START);

   /*
    *  Compute root of bintree for each color band
    */
   if (wfa->wfainfo->color)
   {
      root_state [Y]  = wfa->tree [wfa->tree [wfa->root_state][0]][0];
      root_state [Cb] = wfa->tree [wfa->tree [wfa->root_state][0]][1];
      root_state [Cr] = wfa->tree [wfa->tree [wfa->root_state][1]][0];
   }
   else
      root_state [GRAY] = wfa->root_state;

   /*
    *  Compute maximum level of a linear combination
    */
   for (max_level = 0, state = wfa->basis_states; state < wfa->states; state++)
      if (isedge (wfa->into [state][0][0]) || isedge (wfa->into [state][1][0]))
	 max_level = max (max_level, wfa->level_of_state [state]);
   

   /*
    *  Allocate frame buffer for decoded image
    */
   compute_actual_size (format == FORMAT_4_2_0 ? root_state [Y] : MAXSTATES,
			&width, &height, wfa);
   width  = max (width, orig_width);
   height = max (height, orig_height);
   frame = alloc_image (width, height, wfa->wfainfo->color, format);
   
   /*
    *  Allocate buffers for intermediate state images
    */
   if (wfa->wfainfo->color)
   {
      wfa->level_of_state [wfa->root_state]               = 128;
      wfa->level_of_state [wfa->tree[wfa->root_state][0]] = 128;
      wfa->level_of_state [wfa->tree[wfa->root_state][1]] = 128;
   }
   alloc_state_images (&images, &offsets, frame, root_state, 0, max_level, 
		       format, wfa);

   if (dec_timer)
      dec_timer [0] += prg_timer (&ptimer, STOP);

   /*
    *  Decode all state images, forming the complete image.
    */
   prg_timer (&ptimer, START);
   compute_state_images (max_level, images, offsets, wfa);
   if (dec_timer)
      dec_timer [1] += prg_timer (&ptimer, STOP);

   /*
    *  Cleanup buffers used for intermediate state images
    */
   prg_timer (&ptimer, START);
   free_state_images (max_level, frame->color, images, offsets, root_state, 0,
		      format, wfa);
   
   /*
    *  Crop decoded image if the image size differs.
    */
   if (orig_width != width || orig_height != height)
   {
      frame->height = orig_height;	
      frame->width  = orig_width;	
      if (orig_width != width)		
      {
	 color_e   band;		/* current color band */
	 word_t	  *src, *dst;		/* source and destination pointers */
	 unsigned  y;			/* current row */
	 
	 for (band  = first_band (frame->color);
	      band <= last_band (frame->color); band++)
	 {
	    src = dst = frame->pixels [band];
	    for (y = orig_height; y; y--)
	    {
	       memmove (dst, src, orig_width * sizeof (word_t));
	       dst += orig_width;
	       src += width;
	    }
	    if (format == FORMAT_4_2_0 && band == Y)
	    {
	       orig_width  >>= 1;
	       orig_height >>= 1;
	       width       >>= 1;
	    }
	 }