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

📄 pixops.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 3 页
字号:
                         ((y >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) *                         filter->x.n * filter->y.n * SUBSAMPLE;      guchar *new_outbuf;      guint32 tcolor1, tcolor2;            guchar *outbuf = dest_buf + dest_rowstride * i;      guchar *outbuf_end = outbuf + dest_channels * (render_x1 - render_x0);      if (((i + check_y) >> check_shift) & 1)	{	  tcolor1 = color2;	  tcolor2 = color1;	}      else	{	  tcolor1 = color1;	  tcolor2 = color2;	}      for (j=0; j<filter->y.n; j++)	{	  if (y_start <  0)	    line_bufs[j] = (guchar *)src_buf;	  else if (y_start < src_height)	    line_bufs[j] = (guchar *)src_buf + src_rowstride * y_start;	  else	    line_bufs[j] = (guchar *)src_buf + src_rowstride * (src_height - 1);	  y_start++;	}      dest_x = check_x;      x = render_x0 * x_step + scaled_x_offset;      x_start = x >> SCALE_SHIFT;      while (x_start < 0 && outbuf < outbuf_end)	{	  process_pixel (run_weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * (filter->x.n * filter->y.n), filter->x.n, filter->y.n,			 outbuf, dest_x, dest_channels, dest_has_alpha,			 line_bufs, src_channels, src_has_alpha,			 x >> SCALE_SHIFT, src_width,			 check_size, tcolor1, tcolor2, pixel_func);	  	  x += x_step;	  x_start = x >> SCALE_SHIFT;	  dest_x++;	  outbuf += dest_channels;	}      new_outbuf = (*line_func) (run_weights, filter->x.n, filter->y.n,				 outbuf, dest_x,				 dest_buf + dest_rowstride * i + run_end_index * dest_channels,				 dest_channels, dest_has_alpha,				 line_bufs, src_channels, src_has_alpha,				 x, x_step, src_width, check_size, tcolor1, tcolor2);      dest_x += (new_outbuf - outbuf) / dest_channels;      x = (dest_x - check_x + render_x0) * x_step + scaled_x_offset;      outbuf = new_outbuf;      while (outbuf < outbuf_end)	{	  process_pixel (run_weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * (filter->x.n * filter->y.n), filter->x.n, filter->y.n,			 outbuf, dest_x, dest_channels, dest_has_alpha,			 line_bufs, src_channels, src_has_alpha,			 x >> SCALE_SHIFT, src_width,			 check_size, tcolor1, tcolor2, pixel_func);	  	  x += x_step;	  dest_x++;	  outbuf += dest_channels;	}      y += y_step;    }  g_free (line_bufs);  g_free (filter_weights);}/* Compute weights for reconstruction by replication followed by * sampling with a box filter */static voidtile_make_weights (PixopsFilterDimension *dim,		   double                 scale){  int n = ceil (1 / scale + 1);  double *pixel_weights = g_new (double, SUBSAMPLE * n);  int offset;  int i;  dim->n = n;  dim->offset = 0;  dim->weights = pixel_weights;  for (offset = 0; offset < SUBSAMPLE; offset++)    {      double x = (double)offset / SUBSAMPLE;      double a = x + 1 / scale;      for (i = 0; i < n; i++)        {          if (i < x)            {              if (i + 1 > x)                *(pixel_weights++)  = (MIN (i + 1, a) - x) * scale;              else                *(pixel_weights++) = 0;            }          else            {              if (a > i)                *(pixel_weights++)  = (MIN (i + 1, a) - i) * scale;              else                *(pixel_weights++) = 0;            }       }    }}/* Compute weights for a filter that, for minification * is the same as 'tiles', and for magnification, is bilinear * reconstruction followed by a sampling with a delta function. */static voidbilinear_magnify_make_weights (PixopsFilterDimension *dim,			       double                 scale){  double *pixel_weights;  int n;  int offset;  int i;  if (scale > 1.0)            /* Linear */    {      n = 2;      dim->offset = 0.5 * (1 / scale - 1);    }  else                          /* Tile */    {      n = ceil (1.0 + 1.0 / scale);      dim->offset = 0.0;    }  dim->n = n;  dim->weights = g_new (double, SUBSAMPLE * n);  pixel_weights = dim->weights;  for (offset=0; offset < SUBSAMPLE; offset++)    {      double x = (double)offset / SUBSAMPLE;      if (scale > 1.0)      /* Linear */        {          for (i = 0; i < n; i++)            *(pixel_weights++) = (((i == 0) ? (1 - x) : x) / scale) * scale;        }      else                  /* Tile */        {          double a = x + 1 / scale;          /*           x           * ---------|--.-|----|--.-|-------  SRC           * ------------|---------|---------  DEST           */          for (i = 0; i < n; i++)            {              if (i < x)                {                  if (i + 1 > x)                    *(pixel_weights++) = (MIN (i + 1, a) - x) * scale;                  else                    *(pixel_weights++) = 0;                }              else                {                  if (a > i)                    *(pixel_weights++) = (MIN (i + 1, a) - i) * scale;                  else                    *(pixel_weights++) = 0;                }            }        }    }}/* Computes the integral from b0 to b1 of * * f(x) = x; 0 <= x < 1 * f(x) = 0; otherwise * * We combine two of these to compute the convolution of * a box filter with a triangular spike. */static doublelinear_box_half (double b0, double b1){  double a0, a1;  double x0, x1;  a0 = 0.;  a1 = 1.;  if (a0 < b0)    {      if (a1 > b0)        {          x0 = b0;          x1 = MIN (a1, b1);        }      else        return 0;    }  else    {      if (b1 > a0)        {          x0 = a0;          x1 = MIN (a1, b1);        }      else        return 0;    }  return 0.5 * (x1*x1 - x0*x0);}/* Compute weights for reconstructing with bilinear * interpolation, then sampling with a box filter */static voidbilinear_box_make_weights (PixopsFilterDimension *dim,			   double                 scale){  int n = ceil (1/scale + 3.0);  double *pixel_weights = g_new (double, SUBSAMPLE * n);  double w;  int offset, i;  dim->offset = -1.0;  dim->n = n;  dim->weights = pixel_weights;  for (offset = 0; offset < SUBSAMPLE; offset++)    {      double x = (double)offset / SUBSAMPLE;      double a = x + 1 / scale;      for (i = 0; i < n; i++)        {          w  = linear_box_half (0.5 + i - a, 0.5 + i - x);          w += linear_box_half (1.5 + x - i, 1.5 + a - i);                *(pixel_weights++) = w * scale;        }    }}static voidmake_weights (PixopsFilter     *filter,	      PixopsInterpType  interp_type,	      	      double            scale_x,	      double            scale_y){  switch (interp_type)    {    case PIXOPS_INTERP_NEAREST:      g_assert_not_reached ();      break;    case PIXOPS_INTERP_TILES:      tile_make_weights (&filter->x, scale_x);      tile_make_weights (&filter->y, scale_y);      break;          case PIXOPS_INTERP_BILINEAR:      bilinear_magnify_make_weights (&filter->x, scale_x);      bilinear_magnify_make_weights (&filter->y, scale_y);      break;          case PIXOPS_INTERP_HYPER:      bilinear_box_make_weights (&filter->x, scale_x);      bilinear_box_make_weights (&filter->y, scale_y);      break;    }}void_pixops_composite_color (guchar         *dest_buf,			 int             render_x0,			 int             render_y0,			 int             render_x1,			 int             render_y1,			 int             dest_rowstride,			 int             dest_channels,			 gboolean        dest_has_alpha,			 const guchar   *src_buf,			 int             src_width,			 int             src_height,			 int             src_rowstride,			 int             src_channels,			 gboolean        src_has_alpha,			 double          scale_x,			 double          scale_y,			 PixopsInterpType   interp_type,			 int             overall_alpha,			 int             check_x,			 int             check_y,			 int             check_size,			 guint32         color1,			 guint32         color2){  PixopsFilter filter;  PixopsLineFunc line_func;  #ifdef USE_MMX  gboolean found_mmx = _pixops_have_mmx ();#endif  g_return_if_fail (!(dest_channels == 3 && dest_has_alpha));  g_return_if_fail (!(src_channels == 3 && src_has_alpha));  if (scale_x == 0 || scale_y == 0)    return;  if (!src_has_alpha && overall_alpha == 255)    {      _pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,		     dest_rowstride, dest_channels, dest_has_alpha,		     src_buf, src_width, src_height, src_rowstride, src_channels,		     src_has_alpha, scale_x, scale_y, interp_type);      return;    }  if (interp_type == PIXOPS_INTERP_NEAREST)    {      pixops_composite_color_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1,				      dest_rowstride, dest_channels, dest_has_alpha,				      src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,				      scale_x, scale_y, overall_alpha,				      check_x, check_y, check_size, color1, color2);      return;    }    filter.overall_alpha = overall_alpha / 255.;  make_weights (&filter, interp_type, scale_x, scale_y);#ifdef USE_MMX  if (filter.x.n == 2 && filter.y.n == 2 &&      dest_channels == 4 && src_channels == 4 && src_has_alpha && !dest_has_alpha && found_mmx)    line_func = composite_line_color_22_4a4_mmx_stub;  else#endif    line_func = composite_line_color;    pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1,		  dest_rowstride, dest_channels, dest_has_alpha,		  src_buf, src_width, src_height, src_rowstride, src_channels,		  src_has_alpha, scale_x, scale_y, check_x, check_y, check_size, color1, color2,		  &filter, line_func, composite_pixel_color);  g_free (filter.x.weights);  g_free (filter.y.weights);}/** * _pixops_composite: * @dest_buf: pointer to location to store result * @render_x0: x0 of region of scaled source to store into @dest_buf * @render_y0: y0 of region of scaled source to store into @dest_buf * @render_x1: x1 of region of scaled source to store into @dest_buf * @render_y1: y1 of region of scaled source to store into @dest_buf * @dest_rowstride: rowstride of @dest_buf * @dest_channels: number of channels in @dest_buf * @dest_has_alpha: whether @dest_buf has alpha * @src_buf: pointer to source pixels * @src_width: width of source (used for clipping) * @src_height: height of source (used for clipping) * @src_rowstride: rowstride of source * @src_channels: number of channels in @src_buf * @src_has_alpha: whether @src_buf has alpha * @scale_x: amount to scale source by in X direction * @scale_y: amount to scale source by in Y direction * @interp_type: type of enumeration * @overall_alpha: overall alpha factor to multiply source by *  * Scale source buffer by scale_x / scale_y, then composite a given rectangle * of the result into the destination buffer. **/void_pixops_composite (guchar        *dest_buf,		   int            render_x0,		   int            render_y0,		   int            render_x1,		   int            render_y1,		   int            dest_rowstride,		   int            dest_channels,		   gboolean       dest_has_alpha,		   const guchar  *src_buf,		   int            src_width,		   int            src_height,		   int            src_rowstride,		   int            src_channels,		   gboolean       src_has_alpha,		   double         scale_x,		   double         scale_y,		   PixopsInterpType  interp_type,		   int            overall_alpha){  PixopsFilter filter;  PixopsLineFunc line_func;  #ifdef USE_MMX  gboolean found_mmx = _pixops_have_mmx ();#endif  g_return_if_fail (!(dest_channels == 3 && dest_has_alpha));  g_return_if_fail (!(src_channels == 3 && src_has_alpha));  if (scale_x == 0 || scale_y == 0)    return;  if (!src_has_alpha && overall_alpha == 255)    {      _pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,		     dest_rowstride, dest_channels, dest_has_alpha,		     src_buf, src_width, src_height, src_rowstride, src_channels,		     src_has_alpha, scale_x, scale_y, interp_type);      return;    }  if (interp_type == PIXOPS_INTERP_NEAREST)    {      pixops_composite_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1,				dest_rowstride, dest_channels, dest_has_alpha,				src_buf, src_width, src_height, src_rowstride, src_channels,				src_has_alpha, scale_x, scale_y, overall_alpha);      return;    }    filter.overall_alpha = overall_alpha / 255.;  make_weights (&filter, interp_type, scale_x, scale_y);  if (filter.x.n == 2 && filter.y.n == 2 &&      dest_channels == 4 && src_channels == 4 && src_has_alpha && !dest_has_alpha)    {#ifdef USE_MMX      if (found_mmx)	line_func = composite_line_22_4a4_mmx_stub;      else#endif		line_func = composite_line_22_4a4;    }  else    line_func = composite_line;    pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1,		  dest_rowstride, dest_channels, dest_has_alpha,		  src_buf, src_width, src_height, src_rowstride, src_channels,		  src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0, 		  &filter, line_func, composite_pixel);  g_free (filter.x.weights);  g_free (filter.y.weights);}void_pixops_scale (guchar        *dest_buf,	       int            render_x0,	       int            render_y0,	       int            render_x1,	       int            render_y1,	       int            dest_rowstride,	       int            dest_channels,	       gboolean       dest_has_alpha,	       const guchar  *src_buf,	       int            src_width,	       int            src_height,	       int            src_rowstride,	       int            src_channels,	       gboolean       src_has_alpha,	       double         scale_x,	       double         scale_y,	       PixopsInterpType  interp_type){  PixopsFilter filter;  PixopsLineFunc line_func;#ifdef USE_MMX  gboolean found_mmx = _pixops_have_mmx ();#endif  g_return_if_fail (!(dest_channels == 3 && dest_has_alpha));  g_return_if_fail (!(src_channels == 3 && src_has_alpha));  g_return_if_fail (!(src_has_alpha && !dest_has_alpha));  if (scale_x == 0 || scale_y == 0)    return;  if (interp_type == PIXOPS_INTERP_NEAREST)    {      pixops_scale_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1,			    dest_rowstride, dest_channels, dest_has_alpha,			    src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha,			    scale_x, scale_y);      return;    }    filter.overall_alpha = 1.0;  make_weights (&filter, interp_type, scale_x, scale_y);  if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 3 && src_channels == 3)    {#ifdef USE_MMX      if (found_mmx)	line_func = scale_line_22_33_mmx_stub;      else#endif	line_func = scale_line_22_33;    }  else    line_func = scale_line;    pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1,		  dest_rowstride, dest_channels, dest_has_alpha,		  src_buf, src_width, src_height, src_rowstride, src_channels,		  src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0,		  &filter, line_func, scale_pixel);  g_free (filter.x.weights);  g_free (filter.y.weights);}

⌨️ 快捷键说明

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