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

📄 decoder.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	 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;	    }	 }      }   }   if (dec_timer)      dec_timer [2] += prg_timer (&ptimer, STOP);   return frame;}image_t *decode_state (unsigned state, unsigned level, wfa_t *wfa)/* *  Decode 'state' image of 'wfa' at given 'level'. * *  Return value. *	pointer to decoded state image * *  Side effects: *	'wfa' states > 'state' are removed.   */{   word_t  *domains [2];   image_t *img = Calloc (1, sizeof (image_t));   /*    *  Generate a new state with a 1.0 transition to 'state'    */   remove_states (state + 1, wfa);   append_edge (state + 1, state, 1.0, 0, wfa);   wfa->states = state + 2;   img->color  = NO;   img->width  = width_of_level (level);   img->height = height_of_level (level);   img->format = FORMAT_4_4_4;   img->pixels [GRAY] = decode_range (state + 1, 0, level, domains, wfa);   /*    *  Copy decoded range to the frame buffer    */   {      word_t   *src, *dst;      unsigned	y;	          src = domains [0];      dst = img->pixels [GRAY];      for (y = img->height; y; y--)      {	 memcpy (dst, src, width_of_level (level) * sizeof (word_t));	 src += width_of_level (level);	 dst += img->width;      }      Free (domains [0]);   }   return img;}word_t *decode_range (unsigned range_state, unsigned range_label, unsigned range_level,	      word_t **domain, wfa_t *wfa)/* *  Compute 'wfa' image of range (identified by 'state' and 'label') *  at 'range_level (works as function decode_image()). * *  Return value: *	pointer to the pixels in SHORT format * *  Side effects: *	if 'domain' != NULL then also the domain blocks *	of the corresponding range blocks are generated *      and returned in domain[] *	'wfa->level_of_state []' is changed */{   unsigned   root_state [3];		/* dummy (for alloc_state_images) */   image_t   *state_image;		/* regenerated state image */   word_t   **images;			/* pointer to array of pointers					   to state images */   u_word_t  *offsets;			/* pointer to array of state image					   offsets */   word_t    *range;   enlarge_image (range_level - (wfa->level_of_state [range_state] - 1),		  FORMAT_4_4_4, -1, wfa);   root_state [0] = range_state;   state_image    = alloc_image (width_of_level (range_level + 1),				 height_of_level (range_level + 1),				 NO, FORMAT_4_4_4);   alloc_state_images (&images, &offsets, state_image, NULL, range_state,		       range_level + 1, NO, wfa);   compute_state_images (range_level + 1, images, offsets, wfa);   range = Calloc (size_of_level (range_level), sizeof (word_t));   if ((range_level & 1) == 0)		/* square image */   {      memcpy (range,	      images [range_state + (range_level + 1) * wfa->states]	      + range_label * size_of_level (range_level),	      size_of_level (range_level) * sizeof (word_t));   }   else					/* rectangle */   {      word_t   *src, *dst;      unsigned  y;            src = images [range_state + (range_level + 1) * wfa->states]	    + range_label * width_of_level (range_level);      dst = range;      for (y = height_of_level (range_level); y; y--)      {	 memcpy (dst, src, width_of_level (range_level) * sizeof (word_t));	 dst += width_of_level (range_level);	 src += width_of_level (range_level + 1);      }   }   if (domain != NULL)			/* copy domain images */   {      int      s;			/* domain state */      unsigned edge;			/* counter */		      if (ischild (s = wfa->tree [range_state][range_label]))	 *domain++ = duplicate_state_image (images [s + (range_level)						   * wfa->states],					    offsets [s + (range_level)						    * wfa->states],					    range_level);      for (edge = 0; isedge (s = wfa->into[range_state][range_label][edge]);	   edge++)	 *domain++ = duplicate_state_image (images [s + (range_level)						   * wfa->states],					    offsets [s + (range_level)						    * wfa->states],					    range_level);      *domain = NULL;   }      free_state_images (range_level + 1, NO, images, offsets, NULL, range_state,		      NO, wfa);   free_image (state_image);      return range;}voidsmooth_image (unsigned sf, const wfa_t *wfa, image_t *image)/* *  Smooth 'image' along the partitioning boundaries of the 'wfa' *  with factor 's'. * *  No return value. * *  Side effects: *	pixel values of the 'image' are modified with respect to 's' */{   int	    is, inegs;			/* integer factors of s and 1 - s*/   unsigned state;			   unsigned img_width  = image->width;   unsigned img_height = image->height;   real_t   s 	       = 1.0 - sf / 200.0;   if (s < 0.5 || s >= 1)		/* value out of range */      return;   is 	 = s * 512 + .5;		/* integer representation of s */   inegs = (1 - s) * 512 + .5;		/* integer representation of 1 - s */      for (state = wfa->basis_states;	state < (wfa->wfainfo->color		 ? wfa->tree [wfa->root_state][0]		 : wfa->states); state++)   {      word_t   *bptr   = image->pixels [Y]; /* pointer to right or					       lower line */      unsigned  level  = wfa->level_of_state[state]; /* level of state image */      unsigned  width  = width_of_level (level); /* size of state image */      unsigned  height = height_of_level (level); /* size of state image */            if (wfa->y [state][1] >= img_height || wfa->x [state][1] >= img_width)	 continue;			/* outside visible area */	       if (level % 2)			/* horizontal smoothing */      {	 unsigned  i;			/* line counter */	 word_t   *img1;		/* pointer to left or upper line */	 word_t   *img2;		/* pointer to right or lower line */	 img1 = bptr + (wfa->y [state][1] - 1) * img_width		+ wfa->x [state][1];	 img2 = bptr + wfa->y [state][1] * img_width + wfa->x [state][1];	 	 for (i = min (width, img_width - wfa->x [state][1]); i;	      i--, img1++, img2++)	 {	    int tmp = *img1;	    #ifdef HAVE_SIGNED_SHIFT	    *img1 = (((is * tmp) >> 10) << 1)		    + (((inegs * (int) *img2) >> 10) << 1);	    *img2 = (((is * (int) *img2) >> 10) << 1)		    + (((inegs * tmp) >> 10) << 1);#else /* not HAVE_SIGNED_SHIFT */	    *img1 = (((is * tmp) / 1024) * 2)		    + (((inegs * (int) *img2) / 1024) * 2);	    *img2 = (((is * (int) *img2) / 1024) * 2)		    + (((inegs * tmp) / 1024) *2);#endif /* not HAVE_SIGNED_SHIFT */	 }      }      else				/* vertical smoothing */      {	 unsigned  i;			/* line counter */	 word_t   *img1;		/* pointer to left or upper line */	 word_t   *img2;		/* pointer to right or lower line */	 img1 = bptr + wfa->y [state][1] * img_width + wfa->x [state][1] - 1;	 img2 = bptr + wfa->y [state][1] * img_width + wfa->x [state][1];	 	 for (i = min (height, img_height - wfa->y [state][1]); i;	      i--, img1 += img_width, img2 += img_width)	 {	    int tmp = *img1;	    #ifdef HAVE_SIGNED_SHIFT	    *img1 = (((is * tmp) >> 10) << 1)		    + (((inegs * (int) *img2) >> 10) << 1);	    *img2 = (((is * (int) *img2) >> 10) << 1)		    + (((inegs * tmp) >> 10) << 1);#else /* not HAVE_SIGNED_SHIFT */	    *img1 = (((is * tmp) / 1024) * 2)		    + (((inegs * (int) *img2) / 1024) * 2);	    *img2 = (((is * (int) *img2) / 1024) * 2)		    + (((inegs * tmp) / 1024) *2);#endif /* not HAVE_SIGNED_SHIFT */	 }      }   }}/*****************************************************************************				private code  *****************************************************************************/static voidenlarge_image (int enlarge_factor, format_e format, unsigned y_root,	       wfa_t *wfa)/* *  Enlarge or reduce size of state images by factor 2^'enlarge_factor'. *  Use 4:2:0 subsampling if specified by 'format', else use 4:4:4 format. *  'wfa' root state of the first chroma band is given by 'y_root' + 1. * *  No return value. * *  Side effects: *	coordinates of ranges and motion blocks in the WFA structure 'wfa' *	are modified. */{      if (enlarge_factor != 0 || format == FORMAT_4_2_0)   {      unsigned state;      if (enlarge_factor == 0)      {	 state 		= y_root + 1;	 enlarge_factor = -1;      }      else	 state = wfa->basis_states;            for (; state < wfa->states; state++)      {	 unsigned label, n;	 	 wfa->level_of_state [state]	    = max (wfa->level_of_state [state] + enlarge_factor * 2, 0);	 for (label = 0; label < MAXLABELS; label++)	    if (enlarge_factor > 0)	    {	       wfa->x [state][label] <<= enlarge_factor;	       wfa->y [state][label] <<= enlarge_factor;	       for (n = enlarge_factor; n; n--)	       {		  wfa->mv_tree [state][label].fx *= 2;		  wfa->mv_tree [state][label].fy *= 2;		  wfa->mv_tree [state][label].bx *= 2;		  wfa->mv_tree [state][label].by *= 2;	       }	    }	    else				/* enlarge_factor < 0 */	    {	       wfa->x [state][label] >>= - enlarge_factor;	       wfa->y [state][label] >>= - enlarge_factor;	       for (n = - enlarge_factor; n; n--)	       {		  wfa->mv_tree [state][label].fx /= 2;		  wfa->mv_tree [state][label].fy /= 2;		  wfa->mv_tree [state][label].bx /= 2;		  wfa->mv_tree [state][label].by /= 2;	       }	    }	 if (format == FORMAT_4_2_0 && state == y_root)	    enlarge_factor--;      }   }}static voidcompute_actual_size (unsigned luminance_root,		     unsigned *width, unsigned *height, const wfa_t *wfa)/* *  Compute actual size of the frame represented by the given 'wfa'. *  (The reconstructed frame may get larger than the original due *   to the bintree partitioning.) *  If 'luminance_root' < MAXSTATES then the size of chroma ranges (4:2:0). * *  Return values: *	actual 'width' and 'height' of the decoded frame. */{   unsigned x = 0, y = 0;		/* maximum coordinates */   unsigned state;			/* counter */      for (state = wfa->basis_states; state < wfa->states; state++)      if (isedge (wfa->into [state][0][0]) || isedge (wfa->into [state][1][0]))      {	 unsigned mult = state > luminance_root ? 2 : 1;	 	 x = max ((wfa->x [state][0]		   + width_of_level (wfa->level_of_state [state])) * mult, x);	 y = max ((wfa->y [state][0]		   + height_of_level (wfa->level_of_state [state])) * mult, y);      }   if (x & 1)				/* ensure that image size is even */      x++;   if (y & 1)      y++;   *width  = x;   *height = y;}static voidalloc_state_images (word_t ***images, u_word_t **offsets, const image_t *frame,		    const unsigned *root_state, unsigned range_state,		    unsigned max_level, format_e format, const wfa_t *wfa)/* *  Generate list of 'wfa' state images which have to be computed for *  each level to obtain the decoded 'frame'. 'root_state[]' denotes the *  state images of the three color bands. *  'max_level' fives the max. level of a linear combination. *  Memory is allocated for every required state image. *  Use 4:2:0 subsampling or 4:4:4 'format' for color images. *  If 'range_state' > 0 then rather compute image of 'range_state' than  *  image of 'wfa->root_state'. * *  Return values: *	'*images'	Pointer to array of state image pointers *	'*offsets'	Pointer to array of state image offsets. * *  Side effects: *	The arrays given above are filled with useful values. */{   word_t   **simg;			/* ptr to list of state image ptr's */   u_word_t  *offs;			/* ptr to list of offsets */   unsigned   level;			/* counter */      simg	= Calloc (wfa->states * (max_level + 1), sizeof (word_t *));   offs	= Calloc (wfa->states * (max_level + 1), sizeof (u_word_t));   /*    *  Initialize buffers for those state images which are at 'max_level'.    */   if (range_state > 0)			/* a range is given */   {      simg [range_state + max_level * wfa->states] = frame->pixels [GRAY];      offs [range_state + max_level * wfa->states] = frame->width;   }   else   {      unsigned state;      for (state = wfa->basis_states; state <= root_state [Y]; state++)	 if (wfa->level_of_state [state] == max_level)	 {	    simg [state + max_level * wfa->states]	       = (frame->pixels [Y] + wfa->y [state][0] * frame->width		  + wfa->x [state][0]);	    offs [state + max_level * wfa->states] = frame->width;	 }      if (frame->color)      {	 unsigned width = format == FORMAT_4_2_0 ?			  (frame->width >> 1) : frame->width;	 for (; state < wfa->states; state++)	    if (wfa->level_of_state [state] == max_level)	    {	       simg [state + max_level * wfa->states]		  = (frame->pixels [state > root_state [Cb] ? Cr : Cb]		     + wfa->y [state][0] * width + wfa->x [state][0]);	       offs [state + max_level * wfa->states] = width;	    }      }   }      /*    *  Generate list of state images which must be computed at each level    */   for (level = max_level; level > 0; level--)   {      int      child, domain;      unsigned state, label, edge;            /*       *  Range approximation with child.        */      for (state = 1; state < (range_state > 0 ?			       range_state + 1 : wfa->states); state++)	 if (simg [state + level * wfa->states])	    for (label = 0; label < MAXLABELS; label++)	       if (ischild (child = wfa->tree[state][label]))	       {		  if (isedge (wfa->into[state][label][0]))		  {		     /*		      *  Allocate new image block.		      */		     simg [child + (level - 1) * wfa->states]			= Calloc (size_of_level (level - 1), sizeof (word_t));		     offs [child + (level - 1) * wfa->states]			= width_of_level (level - 1);		  }		  else		  {		     /*		      *  Use image block and offset of parent.		      */		     if (level & 1)	/* split vertically */		     {			simg [child + (level - 1) * wfa->states]			   = (simg [state + level * wfa->states]			      + label * (height_of_level (level - 1)					 * offs [state						+ level * wfa->states]));		     }		     else		/* split horizontally */		     {			simg [child + (level - 1) * wfa->states]			   = (simg [state + level * wfa->states]			      + label * width_of_level (level - 1));		     }		     offs [child + (level - 1) * wfa->states]			= offs [state + level * wfa->states];		  }	       }      /*       *  Range approximation with linear combination        */      for (state = 1; state < (range_state > 0 ?			       range_state + 1 : wfa->states); state++)	 if (simg [state + level * wfa->states])	    for (label = 0; label < MAXLABELS; label++)	       for (edge = 0; isedge (domain = wfa->into[state][label][edge]);		    edge++)	       {		  if (domain > 0	/* don't allocate memory for state 0 */		      && !simg [domain + (level - 1) * wfa->states])		  {		     simg [domain + (level - 1) * wfa->states]			= Calloc (size_of_level (level - 1), sizeof (word_t));		     offs [domain + (level - 1) * wfa->states]			= width_of_level (level - 1);		  }	       }         }   *images  = simg;   *offsets = offs;}static voidfree_state_images (unsigned max_level, bool_t color, word_t **state_image,

⌨️ 快捷键说明

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