⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mwfa.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
       */      if (icosts1 < icosts2)      {	 ifx 	      = fx;	 ify 	      = fy;	 interp_bits  = forward_bits + ibackward_bits;	 interp_costs = icosts1;      }      else      {	 ibx 	      = bx;	 iby 	      = by;	 interp_bits  = iforward_bits + backward_bits;	 interp_costs = icosts2;      }   }   else					/* local exhaustive search */   {      /*       *  Keep forward and backward mv due to time constraints       */      ifx = fx;      ify = fy;      ibx = bx;      iby = by;      interp_bits = forward_bits + backward_bits;      extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],			mt->past->width, wi->half_pixel,			range->x, range->y, fx, fy);      extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY],			mt->future->width, wi->half_pixel,			range->x, range->y, bx, by);      interp_costs = mcpe_norm (mt->original, range->x, range->y,				width, height, mcblock1, mcblock2)		     + (interp_bits + 2) * price; /* code 01 */   }   /*    *  Choose alternative with smallest costs    */   if (forward_costs <= interp_costs)   {      if (forward_costs <= backward_costs)	 mctype = FORWARD;      else	 mctype = BACKWARD;   }   else   {      if (backward_costs <= interp_costs)	 mctype = BACKWARD;      else	 mctype = INTERPOLATED;   }   switch (mctype)   {      case FORWARD:	 range->mv_tree_bits  = 3;	 range->mv_coord_bits = forward_bits;	 range->mv.type       = FORWARD;	 range->mv.fx         = fx;	 range->mv.fy         = fy;	 extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],			   mt->past->width, wi->half_pixel,			   range->x, range->y, range->mv.fx, range->mv.fy);	 get_mcpe (mcpe, mt->original, range->x, range->y, width, height,		   mcblock1, NULL);	 break;      case BACKWARD:	 range->mv_tree_bits  = 3;	 range->mv_coord_bits = backward_bits;	 range->mv.type       = BACKWARD;	 range->mv.bx         = bx;	 range->mv.by         = by;	 extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY],			   mt->future->width, wi->half_pixel,			   range->x, range->y, range->mv.bx, range->mv.by);	 get_mcpe (mcpe, mt->original, range->x, range->y, width, height,		   mcblock1, NULL);	 break;      case INTERPOLATED:	 range->mv_tree_bits  = 2;	 range->mv_coord_bits = interp_bits;	 range->mv.type       = INTERPOLATED;	 range->mv.fx         = ifx;	 range->mv.fy         = ify;	 range->mv.bx         = ibx;	 range->mv.by         = iby;	 extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],			   mt->past->width, wi->half_pixel,			   range->x, range->y, range->mv.fx, range->mv.fy);	 extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY],			   mt->future->width, wi->half_pixel,			   range->x, range->y, range->mv.bx, range->mv.by);	 get_mcpe (mcpe, mt->original, range->x, range->y, width, height,		   mcblock1, mcblock2);	 break;      default:	 break;   }   Free (mcblock1);   Free (mcblock2);}voidfill_norms_table (unsigned x0, unsigned y0, unsigned level,		  const wfa_info_t *wi, motion_t *mt)/* *  Compute norms of difference images for all possible displacements *  in 'mc_forward_norm' and 'mc_backward_norm'. * *  No return value. * *  Side effects: *	'mt->mc_backward_norms' are computed *	'mt->mc_forward_norms' are computed  */{   int	     mx, my;			/* coordinates of motion vector */   unsigned  sr;			/* mv search range +-'sr' pixels */   unsigned  index   = 0;		/* index of motion vector */   unsigned  width   = width_of_level (level);   unsigned  height  = height_of_level (level);   word_t   *mcblock = Calloc (width * height, sizeof (word_t));   sr = wi->half_pixel ? wi->search_range / 2 :  wi->search_range;      for (my = -sr; my < (int) sr; my++)      for (mx = -sr; mx < (int) sr; mx++, index++)      {	  if ((int) x0 + mx < 0 ||	/* block outside visible area */	      x0 + mx + width > mt->original->width || 	      (int) y0 + my < 0 ||	      y0 + my + height > mt->original->height)	  {	     mt->mc_forward_norms [level][index]  = 0.0;	     mt->mc_backward_norms [level][index] = 0.0;	  }	  else	  {	     extract_mc_block (mcblock, width, height, mt->past->pixels [GRAY],			       mt->past->width, wi->half_pixel,			       x0, y0, mx, my);	     mt->mc_forward_norms [level][index]		= mcpe_norm (mt->original, x0, y0, width, height,			     mcblock, NULL);	     if (mt->frame_type == B_FRAME)	     {		extract_mc_block (mcblock, width, height,				  mt->future->pixels [GRAY],				  mt->future->width, wi->half_pixel,				  x0, y0, mx, my);		mt->mc_backward_norms[level][index]		   = mcpe_norm (mt->original, x0, y0, width, height,				mcblock, NULL); 	     }	  }       }   Free (mcblock);}/*****************************************************************************				private code  *****************************************************************************/static voidget_mcpe (word_t *mcpe, const image_t *original, unsigned x0, unsigned y0,	  unsigned width, unsigned height, const word_t *mcblock1,	  const word_t *mcblock2)/* *  Compute MCPE image 'original' - reference. The reference is either *  composed of 'mcblock1' or of ('mcblock1' + 'mcblock2') / 2 (if *  'mcblock2' != NULL).  Coordinates of original block are given by *  'x0', 'y0', 'width', and 'height'. * *  No return value. * *  Side effects: *	'mcpe []' is filled with the delta image */{   const word_t	*oblock;		/* pointer to original image */   assert (mcpe);      oblock = original->pixels [GRAY] + y0 * original->width + x0;   if (mcblock2 != NULL)		/* interpolated prediction */   {      unsigned x, y;			/* current coordinates */            for (y = height; y; y--)       {	 for (x = width; x; x--)	    *mcpe++ = *oblock++ - (*mcblock1++ + *mcblock2++) / 2;	 oblock += original->width - width;      }   }   else					/* forward or backward prediction */   {      unsigned x, y;			/* current coordinates */            for (y = height; y; y--)       {	 for (x = width; x; x--)	    *mcpe++ = *oblock++ - *mcblock1++;      	 oblock += original->width - width;      }   }}static real_tmcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width,	   unsigned height, const word_t *mcblock1, const word_t *mcblock2)/* *  Compute norm of motion compensation prediction error. *  Coordinates of 'original' block are given by ('x0', 'y0') *  and 'width', 'height'. *  Reference blocks are stored in 'mcimage1' and 'mcimage2'. * *  Return value: *	square of norm of difference image */{   unsigned  n;   real_t    norm = 0;   word_t   *mcpe = Calloc (width * height, sizeof (word_t));   word_t   *ptr  = mcpe;      get_mcpe (mcpe, original, x0, y0, width, height, mcblock1, mcblock2);   for (n = height * width; n; n--, ptr++)       norm += square (*ptr / 16);      Free (mcpe);      return norm;}static real_t find_best_mv (real_t price, const image_t *original, const image_t *reference,	      unsigned x0, unsigned y0, unsigned width, unsigned height,	      real_t *bits, int *mx, int *my, const real_t *mc_norms,	      const wfa_info_t *wi, const motion_t *mt)/* *  Find best matching motion vector in image 'reference' to predict *  the block ('x0', 'y0') of size 'width'x'height in image 'original'. * *  Return values: *	prediction costs * *  Side effects: *	'mx', 'my'		coordinates of motion vector *	'bits'			number of bits to encode mv */{   unsigned sr;				/* mv search range +/- 'sr' pixels */   unsigned index;			/* index of motion vector */   int 	    x, y;			/* coordinates of motion vector */   real_t   costs;			/* costs arising if mv is chosen */   real_t   mincosts = MAXCOSTS;	/* best costs so far  */   unsigned bitshift;			/* half_pixel coordinates multiplier */      *mx = *my = 0;   /*    *  Find best fitting motion vector:    *  Use exhaustive search in the interval x,y +- sr (no halfpixel accuracy)    *					  or x,y +- sr/2  (halfpixel accuracy)    */   sr 	    = wi->half_pixel ? wi->search_range / 2 :  wi->search_range;   bitshift = (wi->half_pixel ? 2 : 1);	/* bit0 reserved for halfpixel pred. */      for (index = 0, y = -sr; y < (int) sr; y++)      for (x = -sr; x < (int) sr; x++, index++)	 if ((int) x0 + x >= 0 && (int) y0 + y >= 0 &&		     x0 + x + width  <= original->width && 	     y0 + y + height <= original->height)	 {	    /*	     *  Block is inside visible area.	     *  Compare current costs with 'mincosts'	     */	    costs = mc_norms [index]		    + (mt->xbits [(x + sr) * bitshift]		       + mt->ybits [(y + sr) * bitshift]) * price;	     if (costs < mincosts)	     {		mincosts = costs;		*mx      = x * bitshift;		*my      = y * bitshift;	     }	 }   /*    *  Halfpixel prediction:    *  Compare all nine combinations (-1, y), (0, y), (+1, y) for y = -1,0,+1    */   if (wi->half_pixel)   {      int	rx, ry;			/* halfpixel refinement */      unsigned	bestrx, bestry;		/* coordinates of best mv */      word_t   *mcblock = Calloc (width * height, sizeof (word_t));            bestrx = bestry = 0;      for (rx = -1; rx <= 1; rx++)	 for (ry = -1; ry <= 1; ry++)	 {	    /*	     *  Check if the new motion vector is in allowed area	     */	    if (rx == 0 && ry == 0)	/* already tested */	       continue;	    if ((int) x0 + (*mx / 2) + rx < 0 || /* outside visible area */		x0 + (*mx / 2) + rx + width > original->width ||		(int) y0 + (*my / 2) + ry < 0 || 		y0 + (*my / 2) + ry + height > original->height)	       continue;	    if (*mx + rx < (int) -sr || *mx + rx >= (int) sr ||		*my + ry < (int) -sr || *my + ry >= (int) sr) 	       continue;		/* out of bounds */	    /*	     *  Compute costs of new motion compensation	     */	    extract_mc_block (mcblock, width, height,			      reference->pixels [GRAY],			      reference->width, wi->half_pixel,			      x0, y0, *mx + rx, *my + ry);	    costs = mcpe_norm (mt->original, x0, y0, width, height, mcblock,			       NULL)		    + (mt->xbits [*mx + rx + sr * bitshift]		       + mt->ybits [*my + ry + sr * bitshift]) * price;	    if (costs < mincosts)	    {	       bestrx   = rx;	       bestry   = ry;	       mincosts = costs;	    }	 }      *mx += bestrx;      *my += bestry;      Free (mcblock);   } /* halfpixel */	        *bits = mt->xbits [*mx + sr * bitshift] + mt->ybits [*my + sr * bitshift];   return mincosts;}static real_tfind_second_mv (real_t price, const image_t *original,		const image_t *reference, const word_t *mcblock1,		unsigned xr, unsigned yr, unsigned width, unsigned height,		real_t *bits, int *mx, int *my, const wfa_info_t *wi,		const motion_t *mt)/* *  Search local area (*mx,*my) for best additional mv. *  Overwrite mt->tmpblock. *  TODO check sr = search_range * *  Return values: *	prediction costs * *  Side effects: *	'mx','my'	coordinates of mv *      'bits'		number of bits to encode mv */{   real_t    mincosts = MAXCOSTS;	/* best costs so far  */   unsigned  sr;			/* MV search range +/- 'sr' pixels */   int       x, y;			/* coordinates of motion vector */   int       y0, y1, x0, x1;		/* start/end coord. of search range */   unsigned  bitshift;			/* half_pixel coordinates multiplier */   word_t   *mcblock2 = Calloc (width * height, sizeof (word_t));   sr = wi->search_range;   y0 = max ((int) -sr, *my - (int) local_range);   y1 = min ((int) sr, *my + (int) local_range);   x0 = max ((int) -sr, *mx - (int) local_range);   x1 = min ((int) sr, *mx + (int) local_range);   *mx = *my = 0;   bitshift = (wi->half_pixel ? 2 : 1);	/* bit0 reserved for halfpixel pred. */      for (y = y0; y < y1; y++)      for (x = x0; x < x1; x++)      {	 real_t costs;			/* costs arising if mv is chosen */	 	 /*	  *  Test each mv ('x', 'y') in the given search range:	  *  Get the new motion compensation image from 'reference' and compute	  *  the norm of the motion compensation prediction error	  *  'original' - 0.5 * ('firstmc' + 'reference')	  */	 if ((int) (xr * bitshift) + x < 0 ||	/* outside visible area */	     xr * bitshift + x > (original->width - width) * bitshift ||	     (int) (yr * bitshift) + y < 0 ||	     yr * bitshift + y > (original->height - height) * bitshift)	    continue;	 	 extract_mc_block (mcblock2, width, height,			   reference->pixels [GRAY], reference->width,			   wi->half_pixel, x0, y0, x, y);	 costs  = mcpe_norm (mt->original, x0, y0, width, height,			     mcblock1, mcblock2)		  + (mt->xbits [x + sr] + mt->ybits [y + sr]) * price;	 	 if (costs < mincosts)	 {	    mincosts = costs;	    *mx      = x;	    *my      = y;	 }      }   *bits = mt->xbits [*mx + sr] + mt->ybits [*my + sr];   Free (mcblock2);   return mincosts;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -