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

📄 decoder.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		   u_word_t *offset, const unsigned *root_state,		   unsigned range_state, format_e format, const wfa_t *wfa)/* *  Free memory of state images. *  For more details refer to the inverse function 'alloc_state_images()'. * *  No return value. * *  Side effects: *	arrays 'state_image' and 'offset' are discarded. */{   word_t   marker;			/* ptr is required as a marker */   unsigned level;   if (range_state > 0)   {      state_image [range_state + max_level * wfa->states] = &marker;   }   else   {      unsigned state;            /*       *  Initialize state image array with states at 'max_level'       */      for (state = wfa->basis_states; state <= root_state [Y]; state++)	 if (wfa->level_of_state [state] == max_level)	    state_image [state + max_level * wfa->states] = &marker;      if (color)      {	 if (format == FORMAT_4_2_0)	    level = max_level - 2;	 else	    level = max_level;      	 for (; state < wfa->states; state++)	    if (wfa->level_of_state [state] == level)	       state_image [state + level * wfa->states] = &marker;      }   }      for (level = max_level; level > 0; level--)   {      int      domain, child;      unsigned state, label, edge;      /*       *  Range approximation with child.        */      for (state = 1; state < (range_state > 0 ?			       range_state + 1 : wfa->states); state++)	 if (state_image [state + level * wfa->states])	    for (label = 0; label < MAXLABELS; label++)	       if (ischild (child = wfa->tree[state][label]))	       {		  if (isedge (wfa->into[state][label][0])		      && (state_image [child + (level - 1) * wfa->states]			  != &marker))		     Free (state_image [child + (level - 1) * wfa->states]);		  state_image [child + (level - 1) * wfa->states] = &marker;	       }      /*       *  Range approximation with linear combination        */      for (state = 1; state < (range_state > 0 ?			       range_state + 1 : wfa->states);	   state++)	 if (state_image [state + level * wfa->states])	    for (label = 0; label < MAXLABELS; label++)	       for (edge = 0; isedge (domain = wfa->into[state][label][edge]);		    edge++)		  if (domain > 0			      && (state_image [domain + (level - 1) * wfa->states]			  != NULL)		      && (state_image [domain + (level - 1) * wfa->states]			  != &marker))		  {		     Free (state_image [domain + (level - 1) * wfa->states]);		     state_image [domain + (level - 1) * wfa->states]			= &marker;		  }   }   Free (state_image);   Free (offset);}static voidcompute_state_images (unsigned max_level, word_t **simg,		      const u_word_t *offset, const wfa_t *wfa)/* *  Compute all state images of the 'wfa' at level {1, ... , 'max_level'} *  which are marked in the array 'simg' (offsets of state images *  are given by 'offset'). * *  Warning: Several optimizations are used in this function making  *  it difficult to understand. * *  No return value. * *  Side effects: *	state images (given by pointers in the array 'state_image') *	are computed. */{   unsigned level, state;        /*    *  Copy one-pixel images in case state_image pointer != &final distr.    */   for (state = 1; state < wfa->states; state++)      if (simg [state] != NULL)		/* compute image at level 0 */	 *simg [state] = (int) (wfa->final_distribution[state] * 8 + .5) * 2;   /*    *  Compute images of states    *  Integer arithmetics are used rather than floating point operations.    *  'weight' gives the weight in integer notation    *  'src', 'dst', and 'idst' are pointers to the source and    *  destination pixels (short or integer format), respectively.    *  Short format : one operation per register (16 bit mode).     *  Integer format : two operations per register (32 bit mode).     *  'src_offset', 'dst_offset', and 'dst_offset' give the number of    *  pixels which have to be omitted when jumping to the next image row.    */   for (level = 1; level <= max_level; level++)    {      unsigned label;      unsigned width  = width_of_level (level - 1);      unsigned height = height_of_level (level - 1);            for (state = 1; state < wfa->states; state++)	 if (simg [state + level * wfa->states] != NULL)	    for (label = 0; label < MAXLABELS; label++)	       if (isedge (wfa->into [state][label][0]))	       {		  unsigned  edge;		  int       domain;		  word_t   *range;	/* address of current range */		  bool_t    prediction_used; /* ND prediction found ? */		  /*		   *  Compute address of range image		   */		  if (level & 1)	/* split vertically */		  {		     range = simg [state + level * wfa->states]			     + label * (height_of_level (level - 1)					* offset [state						 + level * wfa->states]);		  }		  else			/* split horizontally */		  {		     range = simg [state + level * wfa->states]			     + label * width_of_level (level - 1);		  }		  /*		   *  Generate the state images by adding the corresponding 		   *  weighted state images:		   *  subimage [label] =		   *       weight_1 * image_1 + ... + weight_n * image_n		   */		  if (!ischild (domain = wfa->tree[state][label]))		     prediction_used = NO;		  else		  {		     unsigned  y;		     word_t   *src;		     word_t   *dst;		     unsigned  src_offset;		     unsigned  dst_offset;		     prediction_used = YES;		     /*		      *  Copy child image		      */		     src        = simg [domain + (level - 1) * wfa->states];		     src_offset = offset [domain + (level - 1) * wfa->states] ;		     dst        = range;		     dst_offset	= offset [state + level * wfa->states];		     for (y = height; y; y--)		     {			memcpy (dst, src, width * sizeof (word_t));			src += src_offset;			dst += dst_offset;		     }		  }		  if (!prediction_used		      && isedge (domain = wfa->into[state][label][0]))		  {		     /*		      *  If prediction is not used then the range is		      *  filled with the first domain. No addition is needed.		      */		     edge = 0;		     if (domain != 0)		     {			int	  weight;			word_t 	 *src;			unsigned  src_offset;			src        = simg [domain + ((level - 1)						     * wfa->states)];			src_offset = offset [domain + ((level - 1)						       * wfa->states)] - width;			weight     = wfa->int_weight [state][label][edge];						if (width == 1)	/* can't add two-pixels in a row */			{			   word_t   *dst;			   unsigned  dst_offset;			   			   dst        = range;			   dst_offset = offset [state + level * wfa->states]					- width;#ifdef HAVE_SIGNED_SHIFT			   *dst++ = ((weight * (int) *src++) >> 10) << 1;#else 					/* not HAVE_SIGNED_SHIFT */			   *dst++ = ((weight * (int) *src++) / 1024) * 2;#endif /* not HAVE_SIGNED_SHIFT */			   if (height == 2) 			   {			      src += src_offset;			      dst += dst_offset;#ifdef HAVE_SIGNED_SHIFT			      *dst++ = ((weight * (int) *src++) >> 10) << 1;#else /* not HAVE_SIGNED_SHIFT */			      *dst++ = ((weight * (int) *src++) / 1024) * 2;#endif /* not HAVE_SIGNED_SHIFT */			   }			}			else			{			   unsigned  y;			   int 	    *idst;			   unsigned  idst_offset;			   			   idst        = (int *) range;			   idst_offset = (offset [state + level * wfa->states]					  - width) / 2;			   for (y = height; y; y--)			   {			      int *comp_dst = idst + (width >> 1);			      			      for (; idst != comp_dst; ) 			      {				 int tmp; /* temp. value of adjacent pixels */#ifdef HAVE_SIGNED_SHIFT#	ifndef WORDS_BIGENDIAN                                 tmp = (((weight * (int) src [1]) >> 10) << 17)				       | (((weight * (int) src [0]) >> 9)					  & 0xfffe);#	else /* not WORDS_BIGENDIAN */                                 tmp = (((weight * (int) src [0]) >> 10) << 17)				       | (((weight * (int) src [1]) >> 9)					  & 0xfffe);#	endif /* not WORDS_BIGENDIAN */#else /* not HAVE_SIGNED_SHIFT */#	ifndef WORDS_BIGENDIAN                                 tmp = (((weight * (int) src [1]) / 1024)					* 131072)				       | (((weight * (int) src [0])/ 512)					  & 0xfffe);#	else /* not WORDS_BIGENDIAN */                                 tmp = (((weight * (int) src [0]) / 1024)					* 131072)				       | (((weight * (int) src [1]) / 512)					  & 0xfffe);#	endif /* not WORDS_BIGENDIAN */#endif /* not HAVE_SIGNED_SHIFT */				 src    +=  2;				 *idst++ = tmp & 0xfffefffe;			      }			      src  += src_offset;			      idst += idst_offset;			   }			}		     }		     else		     {			int weight = (int) (wfa->weight[state][label][edge]					    * wfa->final_distribution[0]					    * 8 + .5) * 2;			/*			 *  Range needs domain 0			 *  (the constant function f(x, y) = 1),			 *  hence a faster algorithm is used.			 */			if (width == 1)	/* can't add two-pixels in a row */			{			   word_t   *dst;			   unsigned  dst_offset;			   			   dst        = range;			   dst_offset = offset [state + level * wfa->states]					- width;			   			   *dst++ = weight;			   if (height == 2)			   {			      dst += dst_offset;			      *dst++ = weight;			   }			}			else			{			   unsigned  x, y;			   int 	    *idst;			   unsigned  idst_offset;			   			   weight      = (weight * 65536) | (weight & 0xffff);			   idst	       = (int *) range;			   idst_offset = offset [state + level * wfa->states]					 / 2;			   for (x = width >> 1; x; x--)			      *idst++ = weight & 0xfffefffe;			   idst += (offset [state + level * wfa->states]				    - width) / 2;			   for (y = height - 1; y; y--)			   {			      memcpy (idst, idst - idst_offset,				      width * sizeof (word_t));			      idst += idst_offset;			   }			}		     }		     edge = 1;		  }		  else		     edge = 0;		  		  /*		   *  Add remaining weighted domain images to current range		   */		  for (; isedge (domain = wfa->into[state][label][edge]);		       edge++)		  {		     if (domain != 0)		     {			word_t 	 *src;			unsigned  src_offset;			int	  weight;			src        = simg [domain + (level - 1) * wfa->states];			src_offset = offset [domain + ((level - 1)						       * wfa->states)] - width;			weight     = wfa->int_weight [state][label][edge];						if (width == 1)	/* can't add two-pixels in a row */			{			   word_t   *dst;			   unsigned  dst_offset;			   			   dst        = range;			   dst_offset = offset [state + level * wfa->states]					- width;#ifdef HAVE_SIGNED_SHIFT			   *dst++ += ((weight * (int) *src++) >> 10) << 1;#else /* not HAVE_SIGNED_SHIFT */			   *dst++ += ((weight * (int) *src++) / 1024) * 2;#endif /* not HAVE_SIGNED_SHIFT */			   if (height == 2) 			   {			      src += src_offset;			      dst += dst_offset;#ifdef HAVE_SIGNED_SHIFT			      *dst++ += ((weight * (int) *src++) >> 10) << 1;#else /* not HAVE_SIGNED_SHIFT */			      *dst++ += ((weight * (int) *src++) / 1024) * 2;#endif /* not HAVE_SIGNED_SHIFT */			   }			}			else			{			   int 	    *idst;			   unsigned  idst_offset;			   unsigned  y;			   			   idst        = (int *) range;			   idst_offset = (offset [state + level * wfa->states]					  - width) / 2;			   			   for (y = height; y; y--)			   {			      int *comp_dst = idst + (width >> 1);			      			      for (; idst != comp_dst;) 			      {				 int tmp; /* temp. value of adjacent pixels */#ifdef HAVE_SIGNED_SHIFT#	ifndef WORDS_BIGENDIAN                                 tmp = (((weight * (int) src [1]) >> 10) << 17)				       | (((weight * (int) src [0]) >> 9)					  & 0xfffe);#	else /* not WORDS_BIGENDIAN */                                 tmp = (((weight * (int)src [0]) >> 10) << 17)				       | (((weight * (int)src [1]) >> 9)					  & 0xfffe);#	endif /* not WORDS_BIGENDIAN */#else /* not HAVE_SIGNED_SHIFT */#	ifndef WORDS_BIGENDIAN                                 tmp = (((weight * (int) src [1]) / 1024)					* 131072)				       | (((weight * (int) src [0])/ 512)					  & 0xfffe);#	else /* not WORDS_BIGENDIAN */                                 tmp = (((weight * (int) src [0]) / 1024)					* 131072)				       | (((weight * (int) src [1])/ 512)					  & 0xfffe);#	endif /* not WORDS_BIGENDIAN */#endif /* not HAVE_SIGNED_SHIFT */				 src +=  2;				 *idst = (*idst + tmp) & 0xfffefffe;				 idst++;			      }			      src  += src_offset;			      idst += idst_offset;			   }			}		     }		     else		     {			int weight = (int) (wfa->weight[state][label][edge]					    * wfa->final_distribution[0]					    * 8 + .5) * 2;			/*			 *  Range needs domain 0			 *  (the constant function f(x, y) = 1),			 *  hence a faster algorithm is used.			 */			if (width == 1)	/* can't add two-pixels in a row */			{			   word_t   *dst;			   unsigned  dst_offset;			   			   dst        = range;			   dst_offset = offset [state + level * wfa->states]					- width;			   			   *dst++ += weight;			   if (height == 2)			   {			      dst    += dst_offset;			      *dst++ += weight;			   }			}			else			{			   int 	    *idst;			   unsigned  idst_offset;			   unsigned  y;			   			   weight      = (weight * 65536) | (weight & 0xffff);			   idst	       = (int *) range;			   idst_offset = (offset [state + level * wfa->states]					  - width) /2;			   			   for (y = height; y; y--)			   {			      int *comp_dst = idst + (width >> 1);			      			      for (; idst != comp_dst; )			      {				 *idst = (*idst + weight) & 0xfffefffe;                                 idst++;			      }			      idst += idst_offset;			   }			}		     }		  }	       }    }}static word_t *duplicate_state_image (const word_t *domain, unsigned offset, unsigned level)/* *  Allocate new memory block 'pixels' and copy pixel values of 'domain'  *  (size and pixel offset are given by 'level' and 'offset') *  to the lock 'pixels'. * *  Return value: *	pointer to the new domain block */{   word_t *dst, *pixels;   int	   y, n;   dst = pixels = Calloc (size_of_level (level), sizeof (word_t));   if (domain)      for (y = height_of_level (level); y; y--)      {	 memcpy (dst, domain, width_of_level (level) * sizeof (word_t));	 dst    += width_of_level (level);	 domain += offset;      }   else					/* state 0 */      for (n = size_of_level (level); n; n--)	 *dst++ = (int) (128 * 8 + .5) * 2;   return pixels;}

⌨️ 快捷键说明

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