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

📄 pixops.c

📁 这是符合Linux操作系统标准的POIXS 的pixops-2.0.5源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef USE_MMXstatic uint8 *scale_line_22_33_mmx_stub (int *weights,                           int n_x,                           int n_y,                           uint8 *dest,                           int dest_x,                           uint8 *dest_end,                           int dest_bytes_per_pixel,                           int dest_depth,                           int dest_has_alpha,                           uint8 **src,                           int src_bytes_per_pixel,                           int src_depth,                           uint32 *src_colormap,                           boolean src_has_alpha,                           int x_init,                           int x_step,                           int src_width,                           int check_size,                           uint32 color1,                           uint32 color2){   uint32 mmx_weights[16][8];   int j;   for (j=0; j<16; j++) {      mmx_weights[j][0] = 0x00010001 * (weights[4*j] >> 8);      mmx_weights[j][1] = 0x00010001 * (weights[4*j] >> 8);      mmx_weights[j][2] = 0x00010001 * (weights[4*j + 1] >> 8);      mmx_weights[j][3] = 0x00010001 * (weights[4*j + 1] >> 8);      mmx_weights[j][4] = 0x00010001 * (weights[4*j + 2] >> 8);      mmx_weights[j][5] = 0x00010001 * (weights[4*j + 2] >> 8);      mmx_weights[j][6] = 0x00010001 * (weights[4*j + 3] >> 8);      mmx_weights[j][7] = 0x00010001 * (weights[4*j + 3] >> 8);   }   return pixops_scale_line_22_33_mmx (mmx_weights, dest, src[0], src[1], x_step, dest_end, x_init);}#endif /* USE_MMX */static uint8 *scale_line_22_33 (int *weights,                  int n_x,                  int n_y,                  uint8 *dest,                  int dest_x,                  uint8 *dest_end,                  int dest_bytes_per_pixel,                  int dest_depth,                  int dest_has_alpha,                  uint8 **src,                  int src_bytes_per_pixel,                  int src_depth,                  uint32 *src_colormap,                  boolean src_has_alpha,                  int x_init,                  int x_step,                  int src_width,                  int check_size,                  uint32 color1,                  uint32 color2){   int x = x_init;   uint8 *src0 = src[0];   uint8 *src1 = src[1];   while (dest < dest_end) {      unsigned int r, g, b;      int x_scaled = x >> SCALE_SHIFT;      int *pixel_weights;      uint8 *q0, *q1;      int w1, w2, w3, w4;      q0 = src0 + x_scaled * 3;      q1 = src1 + x_scaled * 3;      pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * 4;      w1 = pixel_weights[0];      w2 = pixel_weights[1];      w3 = pixel_weights[2];      w4 = pixel_weights[3];      r = w1 * q0[0];      g = w1 * q0[1];      b = w1 * q0[2];      r += w2 * q0[3];      g += w2 * q0[4];      b += w2 * q0[5];      r += w3 * q1[0];      g += w3 * q1[1];      b += w3 * q1[2];      r += w4 * q1[3];      g += w4 * q1[4];      b += w4 * q1[5];      dest[0] = (r + 0x8000) >> 16;      dest[1] = (g + 0x8000) >> 16;      dest[2] = (b + 0x8000) >> 16;      dest += 3;      x += x_step;   }   return dest;}static voidprocess_pixel (int *weights,               int n_x,               int n_y,               uint8 *dest,               int dest_x,               int dest_bytes_per_pixel,               int dest_depth,               int dest_has_alpha,               uint8 **src,               int src_bytes_per_pixel,               int src_depth,               uint32 *src_colormap,               boolean src_has_alpha,               int x_start,               int src_width,               int check_size,               uint32 color1,               uint32 color2,               PixopsPixelFunc pixel_func){   unsigned int r = 0, g = 0, b = 0, a = 0;   int i, j;   for (i=0; i<n_y; i++)   {      int *line_weights  = weights + n_x * i;      for (j=0; j<n_x; j++)      {         unsigned int ta;         uint8 *q;         uint32 p;         if (x_start + j < 0)            q = src[i];         else if (x_start + j < src_width)            q = src[i] + (x_start + j) * src_bytes_per_pixel;         else            q = src[i] + (src_width - 1) * src_bytes_per_pixel;         if (src_has_alpha)            ta = q[3] * line_weights[j];         else            ta = 0xff * line_weights[j];         p = load_pixel (q, src_bytes_per_pixel, src_depth, src_colormap);         r += ta * (((uint8 *) &p)[0]);         g += ta * (((uint8 *) &p)[1]);         b += ta * (((uint8 *) &p)[2]);         a += ta;      }   }   (*pixel_func) (dest, dest_x, dest_bytes_per_pixel, dest_depth, dest_has_alpha,                  src_has_alpha, check_size, color1, color2, r, g, b, a);}static voidpixops_process (uint8 *dest_buf,                int render_x0,                int render_y0,                int render_x1,                int render_y1,                int dest_rowstride,                int dest_bytes_per_pixel,                int dest_depth,                boolean dest_has_alpha,                const uint8   *src_buf,                int src_width,                int src_height,                int src_rowstride,                int src_bytes_per_pixel,                int src_depth,                uint32 *src_colormap,                boolean src_has_alpha,                double scale_x,                double scale_y,                int check_x,                int check_y,                int check_size,                uint32 color1,                uint32 color2,                PixopsFilter *filter,                PixopsLineFunc line_func,                PixopsPixelFunc pixel_func){   int i, j;   int x, y;			/* X and Y position in source (fixed_point) */   uint8 **line_bufs = mnew (uint8 *, filter->n_y);   int x_step = (1 << SCALE_SHIFT) / scale_x; /* X step in source (fixed point) */   int y_step = (1 << SCALE_SHIFT) / scale_y; /* Y step in source (fixed point) */   int check_shift = check_size ? get_check_shift (check_size) : 0;   int scaled_x_offset = floor (filter->x_offset * (1 << SCALE_SHIFT));   /* Compute the index where we run off the end of the source buffer. The    * furthest source pixel we access at index i is:    *    *  ((render_x0 + i) * x_step + scaled_x_offset) >> SCALE_SHIFT + filter->n_x - 1    *    * So, run_end_index is the smallest i for which this pixel is src_width,    * i.e, for which:    *    *  (i + render_x0) * x_step >= ((src_width - filter->n_x + 1) << SCALE_SHIFT) - scaled_x_offset    *    */#define MYDIV(a,b) ((a) > 0 ? (a) / (b) : ((a) - (b) + 1) / (b))    /* Division so that -1/5 = -1 */   int run_end_x = (((src_width - filter->n_x + 1) << SCALE_SHIFT) - scaled_x_offset);   int run_end_index = MYDIV (run_end_x + x_step - 1, x_step) - render_x0;   run_end_index = MIN (run_end_index, render_x1 - render_x0);   y = render_y0 * y_step + floor (filter->y_offset * (1 << SCALE_SHIFT));   for (i = 0; i < (render_y1 - render_y0); i++)   {      int dest_x;      int y_start = y >> SCALE_SHIFT;      int x_start;      int *run_weights = filter->weights         + ((y >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK)         * filter->n_x * filter->n_y         * SUBSAMPLE;      uint8 *new_outbuf;      uint32 tcolor1, tcolor2;      uint8 *outbuf = dest_buf + dest_rowstride * i;      uint8 *outbuf_end = outbuf + dest_bytes_per_pixel * (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->n_y; j++)      {         if (y_start <  0)            line_bufs[j] = (uint8 *)src_buf;         else if (y_start < src_height)            line_bufs[j] = (uint8 *)src_buf + src_rowstride * y_start;         else            line_bufs[j] = (uint8 *)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->n_x * filter->n_y),                        filter->n_x, filter->n_y,                        outbuf, dest_x, dest_bytes_per_pixel, dest_depth, dest_has_alpha,                        line_bufs, src_bytes_per_pixel, src_depth, src_colormap,                        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_bytes_per_pixel;      }      new_outbuf = (*line_func) (run_weights, filter->n_x, filter->n_y,                                 outbuf, dest_x,                                 dest_buf + dest_rowstride * i                                  + run_end_index * dest_bytes_per_pixel,                                 dest_bytes_per_pixel, dest_depth, dest_has_alpha,                                 line_bufs, src_bytes_per_pixel, src_depth,                                 src_colormap, src_has_alpha,                                 x, x_step, src_width, check_size, tcolor1, tcolor2);      dest_x += (new_outbuf - outbuf) / dest_bytes_per_pixel;      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->n_x * filter->n_y),                        filter->n_x, filter->n_y,                        outbuf, dest_x, dest_bytes_per_pixel,                        dest_depth, dest_has_alpha,                        line_bufs, src_bytes_per_pixel, src_depth, src_colormap,                        src_has_alpha, x >> SCALE_SHIFT, src_width,                        check_size, tcolor1, tcolor2, pixel_func);         x += x_step;         dest_x++;         outbuf += dest_bytes_per_pixel;      }      y += y_step;   }   free (line_bufs);}static voidcorrect_total (int    *weights,               int    n_x,               int    n_y,               int    total,               double overall_alpha){   int correction = (int)(0.5 + 65536 * overall_alpha) - total;   int i;   for (i = n_x * n_y - 1; i >= 0; i--) {      if (*(weights + i) + correction >= 0) {         *(weights + i) += correction;         break;      }   }}static voidtile_make_weights (PixopsFilter *filter, double x_scale, double y_scale, double overall_alpha){   int i_offset, j_offset;   int n_x = ceil(1/x_scale + 1);   int n_y = ceil(1/y_scale + 1);   filter->x_offset = 0;   filter->y_offset = 0;   filter->n_x = n_x;   filter->n_y = n_y;   filter->weights = mnew (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y);   for (i_offset=0; i_offset<SUBSAMPLE; i_offset++) {      for (j_offset=0; j_offset<SUBSAMPLE; j_offset++)      {         int *pixel_weights = filter->weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y;         double x = (double)j_offset / SUBSAMPLE;         double y = (double)i_offset / SUBSAMPLE;         int i,j;         int total = 0;         for (i = 0; i < n_y; i++)         {            double tw, th;            if (i < y)            {               if (i + 1 > y)                  th = MIN(i+1, y + 1/y_scale) - y;               else                  th = 0;            }            else            {               if (y + 1/y_scale > i)                  th = MIN(i+1, y + 1/y_scale) - i;               else                  th = 0;            }            for (j = 0; j < n_x; j++)            {               int weight;               if (j < x)               {                  if (j + 1 > x)                     tw = MIN(j+1, x + 1/x_scale) - x;                  else                     tw = 0;               }               else               {                  if (x + 1/x_scale > j)                     tw = MIN(j+1, x + 1/x_scale) - j;                  else                     tw = 0;               }               weight = 65536 * tw * x_scale * th * y_scale * overall_alpha + 0.5;               total += weight;               *(pixel_weights + n_x * i + j) = weight;            }         }         correct_total (pixel_weights, n_x, n_y, total, overall_alpha);      }   }}static voidbilinear_make_fast_weights (PixopsFilter *filter,                            double x_scale,                            double y_scale,                            double overall_alpha){   int i_offset, j_offset;   double *x_weights, *y_weights;   int n_x, n_y;   if (x_scale > 1.0)		/* Bilinear */   {      n_x = 2;      filter->x_offset = 0.5 * (1/x_scale - 1);   }   else				/* Tile */   {      n_x = ceil(1.0 + 1.0/x_scale);      filter->x_offset = 0.0;   }   if (y_scale > 1.0)		/* Bilinear */   {      n_y = 2;      filter->y_offset = 0.5 * (1/y_scale - 1);   }   else				/* Tile */   {      n_y = ceil(1.0 + 1.0/y_scale);      filter->y_offset = 0.0;   }   filter->n_y = n_y;   filter->n_x = n_x;   filter->weights = mnew (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y);   x_weights = mnew (double, n_x);   y_weights = mnew (double, n_y);   for (i_offset=0; i_offset<SUBSAMPLE; i_offset++) {      for (j_offset=0; j_offset<SUBSAMPLE; j_offset++)      {         int *pixel_weights = filter->weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y;         double x = (double)j_offset / SUBSAMPLE;         double y = (double)i_offset / SUBSAMPLE;         int i,j;         int total = 0;         if (x_scale > 1.0)	/* Bilinear */         {            for (i = 0; i < n_x; i++)            {               x_weights[i] = ((i == 0) ? (1 - x) : x) / x_scale;            }         }         else			/* Tile */         {            /*           x             * ---------|--.-|----|--.-|-------  SRC             * ------------|---------|---------  DEST             */

⌨️ 快捷键说明

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