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

📄 mwfa.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  mwfa.c:		Initialization of MWFA coder * *  Written by:		Michael Unger *			Ullrich Hafner *		 *  This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) *  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"#include <ctype.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 "misc.h"#include "cwfa.h"#include "image.h"#include "mwfa.h"#include "motion.h"/*****************************************************************************			     local variables  *****************************************************************************/unsigned mv_code_table [33][2] =/* *  MPEG's huffman code for vector components. Format: code_value, length */{   {0x19, 11}, {0x1b, 11}, {0x1d, 11}, {0x1f, 11}, {0x21, 11}, {0x23, 11},   {0x13, 10}, {0x15, 10}, {0x17, 10}, {0x7, 8}, {0x9, 8}, {0xb, 8}, {0x7, 7},   {0x3, 5}, {0x3, 4}, {0x3, 3}, {0x1, 1}, {0x2, 3}, {0x2, 4}, {0x2, 5},   {0x6, 7}, {0xa, 8}, {0x8, 8}, {0x6, 8}, {0x16, 10}, {0x14, 10}, {0x12, 10},    {0x22, 11}, {0x20, 11}, {0x1e, 11}, {0x1c, 11}, {0x1a, 11}, {0x18, 11}};static const unsigned local_range = 6;/*****************************************************************************				prototypes  *****************************************************************************/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);static real_tmcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width,	   unsigned height, const word_t *mcblock1, const word_t *mcblock2);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);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);/*****************************************************************************				public code  *****************************************************************************/motion_t *alloc_motion (const wfa_info_t *wi)/* *  Motion structure constructor. *  Allocate memory for the motion structure and *  fill in default values specified by 'wi'. * *  Return value: *	pointer to the new option structure or NULL on error */{   int	     dx;			/* motion vector coordinate */   unsigned  level;   unsigned range_size = wi->half_pixel			 ? square (wi->search_range)			 : square (2 * wi->search_range);   motion_t *mt        = Calloc (1, sizeof (motion_t));      mt->original = NULL;   mt->past     = NULL;   mt->future   = NULL;   mt->xbits 	= Calloc (2 * wi->search_range, sizeof (real_t));   mt->ybits 	= Calloc (2 * wi->search_range, sizeof (real_t));   for (dx = -wi->search_range; dx < (int) wi->search_range; dx++)   {      mt->xbits [dx + wi->search_range]	 = mt->ybits [dx + wi->search_range]	 = mv_code_table [dx + wi->search_range][1];   }      mt->mc_forward_norms = Calloc (MAXLEVEL, sizeof (real_t *));   mt->mc_backward_norms = Calloc (MAXLEVEL, sizeof (real_t *));      for (level = wi->p_min_level; level <= wi->p_max_level; level++)   {      mt->mc_forward_norms  [level] = Calloc (range_size, sizeof (real_t));      mt->mc_backward_norms [level] = Calloc (range_size, sizeof (real_t));   }   return mt;}voidfree_motion (motion_t *mt)/* *  Motion struct destructor: *  Free memory of 'motion' struct. * *  No return value. * *  Side effects: *	structure 'motion' is discarded. */{   unsigned level;   Free (mt->xbits);   Free (mt->ybits);   for (level = 0; level < MAXLEVEL; level++)   {      if (mt->mc_forward_norms [level])	 Free (mt->mc_forward_norms [level]);      if (mt->mc_backward_norms [level])	 Free (mt->mc_backward_norms [level]);   }   Free (mt->mc_forward_norms);   Free (mt->mc_backward_norms);   Free (mt);}voidsubtract_mc (image_t *image, const image_t *past, const image_t *future,	     const wfa_t *wfa)/* *  Subtract motion compensation from chrom channels of 'image'. *  Reference frames are given by 'past' and 'future'. * *  No return values. */{   unsigned  state, label;   word_t   *mcblock1 = Calloc (size_of_level (wfa->wfainfo->p_max_level),				sizeof (word_t));   word_t   *mcblock2 = Calloc (size_of_level (wfa->wfainfo->p_max_level),				sizeof (word_t));   for (state = wfa->basis_states; state < wfa->states; state++)      for (label = 0; label < MAXLABELS; label++)	 if (wfa->mv_tree [state][label].type != NONE)	 {	    color_e  band;		/* current color band */	    unsigned width, height;	/* size of mcblock */	    unsigned offset;		/* remaining pixels in original */	    	    width  = width_of_level (wfa->level_of_state [state] - 1);	    height = height_of_level (wfa->level_of_state [state] - 1);	    offset = image->width - width;	    	    switch (wfa->mv_tree [state][label].type)	    {	       case FORWARD:		  for (band  = first_band (image->color) + 1;		       band <= last_band (image->color); band++)		  {		     unsigned  y;	/* row of block */		     word_t   *mc1;	/* pixel in MC block 1 */		     word_t   *orig;	/* pixel in original image */		     		     extract_mc_block (mcblock1, width, height,				       past->pixels [band], past->width,				       wfa->wfainfo->half_pixel,				       wfa->x [state][label],				       wfa->y [state][label],				       (wfa->mv_tree [state][label].fx / 2)				       * 2,				       (wfa->mv_tree [state][label].fy / 2)				       * 2);		     mc1  = mcblock1;		     orig = image->pixels [band] + wfa->x [state][label]			    + wfa->y [state][label] * image->width;		      		     for (y = height; y; y--)		     {			unsigned x;	/* column of block */						for (x = width; x; x--)			   *orig++ -= *mc1++;			orig += offset;		     }		  }		  break;	       case BACKWARD:		  for (band  = first_band (image->color) + 1;		       band <= last_band (image->color); band++)		  {		     unsigned  y;	/* row of block */		     word_t   *mc1;	/* pixel in MC block 1 */		     word_t   *orig;	/* pixel in original image */		     		     extract_mc_block (mcblock1, width, height,				       future->pixels [band], future->width,				       wfa->wfainfo->half_pixel,				       wfa->x [state][label],				       wfa->y [state][label],				       (wfa->mv_tree [state][label].bx / 2)				       * 2,				       (wfa->mv_tree [state][label].by / 2)				       * 2);		     mc1  = mcblock1;		     orig = image->pixels [band] + wfa->x [state][label]			    + wfa->y [state][label] * image->width;		     		     for (y = height; y; y--)		     {			unsigned x;	/* column of block */						for (x = width; x; x--)			   *orig++ -= *mc1++;			orig += offset;		     }		  }		  break;	       case INTERPOLATED:		  for (band  = first_band (image->color) + 1;		       band <= last_band (image->color); band++)		  {		     unsigned  y;	/* row of block */		     word_t   *mc1;	/* pixel in MC block 1 */		     word_t   *mc2;	/* pixel in MC block 2 */		     word_t   *orig;	/* pixel in original image */		     		     extract_mc_block (mcblock1, width, height,				       past->pixels [band], past->width,				       wfa->wfainfo->half_pixel,				       wfa->x [state][label],				       wfa->y [state][label],				       (wfa->mv_tree[state][label].fx / 2)				       * 2,				       (wfa->mv_tree[state][label].fy / 2)				       * 2);		     extract_mc_block (mcblock2, width, height,				       future->pixels [band], future->width,				       wfa->wfainfo->half_pixel,				       wfa->x [state][label],				       wfa->y [state][label],				       (wfa->mv_tree[state][label].bx / 2)				       * 2,				       (wfa->mv_tree[state][label].by / 2)				       * 2);		     mc1  = mcblock1;		     mc2  = mcblock2;		     orig = image->pixels [band] + wfa->x [state][label]			    + wfa->y [state][label] * image->width;		     		     for (y = height; y; y--)		     {			unsigned x;	/* column of block */						for (x = width; x; x--)			   *orig++ -= (*mc1++ + *mc2++) / 2;			orig += offset;		     }		  }		  break;	       default:		  break;	    }	 }   Free (mcblock1);   Free (mcblock2);}voidfind_P_frame_mc (word_t *mcpe, real_t price, range_t *range,		 const wfa_info_t *wi, const motion_t *mt)/* *  Determine best motion vector for P-frame. * *  No return value. * *  Side effects: *            range->mvt_bits  (# of mv-tree bits) *            range->mvxybits  (# of bits for vector components) *            mt->mcpe         (MCPE in scan-order) */{   unsigned  width   = width_of_level (range->level);   unsigned  height  = height_of_level (range->level);   word_t   *mcblock = Calloc (width * height, sizeof (word_t));      range->mv_tree_bits = 1;   range->mv.type      = FORWARD;   /*    *  Find best matching forward prediction    */   find_best_mv (price, mt->original, mt->past, range->x, range->y,		 width, height, &range->mv_coord_bits, &range->mv.fx,		 &range->mv.fy, mt->mc_forward_norms [range->level], wi, mt);   /*    *  Compute MCPE    */   extract_mc_block (mcblock, 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,	     mcblock, NULL);   Free (mcblock);}voidfind_B_frame_mc (word_t *mcpe, real_t price, range_t *range,		 const wfa_info_t *wi, const motion_t *mt)/* *  Determines best motion compensation for B-frame. *  Steps: *         1)  find best forward motion vector *         2)  find best backward motion vector *         3)  try both motion vectors together (interpolation) *         4)  choose best mode (FORWARD, BACKWARD or INTERPOLATED) *  Bitcodes: *    FORWARD      000 *    BACKWARD     001 *    INTERPOLATED  01 *   *  Return values: *            range->mvt_bits  (# of mv-tree bits) *            range->mvxybits  (# of bits for vector components) *            mt->mcpe         (MCPE in scan-order) */{   mc_type_e  mctype;			/* type of motion compensation */   real_t     forward_costs;		/* costs of FORWARD mc */   real_t     backward_costs;		/* costs of BACKWARD mc */   real_t     interp_costs;		/* costs of INTERPOLATED mc */   real_t     forward_bits;		/* bits for FORWARD mc */   real_t     backward_bits;		/* bits for BACKWARD mc */   real_t     interp_bits;		/* bits for INTERPOLATED mc */   int	      fx,  fy;			/* coordinates FORWARD mc */   int	      bx,  by;			/* coordinates BACKWARD mc */   int	      ifx, ify;			/* coordinates forw. INTERPOLATED mc */   int	      ibx, iby;			/* coordinates back. INTERPOLATED mc */   unsigned   width    = width_of_level (range->level);   unsigned   height   = height_of_level (range->level);   word_t    *mcblock1 = Calloc (width * height, sizeof (word_t));   word_t    *mcblock2 = Calloc (width * height, sizeof (word_t));      /*    *  Forward interpolation: use past frame as reference    */   forward_costs = find_best_mv (price, mt->original, mt->past,				 range->x, range->y, width, height,				 &forward_bits, &fx, &fy,				 mt->mc_forward_norms [range->level], wi, mt)		   + 3 * price; /* code 000 */   /*    *  Backward interpolation: use future frame as reference    */   backward_costs = find_best_mv (price, mt->original, mt->future,				  range->x, range->y, width, height,				  &backward_bits, &bx, &by,				  mt->mc_backward_norms [range->level], wi, mt)		    + 3 * price; /* code 001 */   /*    *  Bidirectional interpolation: use both past and future frame as reference    */   if (wi->cross_B_search)    {      real_t icosts1;			/* costs interpolation alternative 1 */      real_t icosts2;			/* costs interpolation alternative 2 */      real_t ibackward_bits;		/* additional bits alternative 1 */      real_t iforward_bits;		/* additional bits alternative 1 */            /*       *  Alternative 1: keep forward mv and vary backward mv locally       */      extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY],			mt->past->width, wi->half_pixel,			range->x, range->y, fx, fy);      ibx = bx;				/* start with backward coordinates */      iby = by;      icosts1 = find_second_mv (price, mt->original, mt->future,				mcblock1, range->x, range->y, width, height,				&ibackward_bits, &ibx, &iby, wi, mt)		+ (forward_bits + 2) * price; /* code 01 */      /*       *  Alternative 2: Keep backward mv and vary forward mv locally       */      extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY],			mt->future->width, wi->half_pixel,			range->x, range->y, bx, by);      ifx = fx;      ify = fy;      icosts2 = find_second_mv (price, mt->original, mt->past,				mcblock1, range->x, range->y, width, height,				&iforward_bits, &ifx, &ify, wi, mt)		+ (backward_bits + 2) * price; /* code 01 */            /*       *  Choose best alternative

⌨️ 快捷键说明

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