コード例 #1
0
ファイル: ripple.c プロジェクト: Amerekanets/gimp
static void
ripple_horizontal (gint x,
                 gint y,
                 guchar *dest,
                 gint bpp,
                 gpointer data)
{
  RippleParam_t *param = (RippleParam_t*) data;
  GimpPixelFetcher *pft;
  guchar   pixel[2][4];
  gdouble  needx;
  gint     xi, xi_a, width;

  pft = param->pft;
  width = param->width;

  needx = x + displace_amount(y);
  xi = floor (needx);
  xi_a = xi+1;
  /* Tile the image. */
  if (rvals.edges == WRAP)
    {
      needx = fmod((needx), width);
      while (needx < 0.0)
	needx += width;
      xi = (xi % width);
      while (xi < 0)
	xi += width;
      xi_a = (xi+1) % width;
    }
  /* Smear out the edges of the image by repeating pixels. */
  else if (rvals.edges == SMEAR)
    {
      needx = CLAMP(needx , 0, width - 1);
      xi    = CLAMP(xi    , 0, width - 1);
      xi_a  = CLAMP(xi + 1, 0, width - 1);
    }

  if (rvals.antialias)
    {
      if (xi >= 0 && xi < width)
	gimp_pixel_fetcher_get_pixel (pft, xi,   y, pixel[0]);
      else
	memset(pixel[0], 0, 4);
      if (xi_a >= 0 && xi_a < width)
	gimp_pixel_fetcher_get_pixel (pft, xi_a, y, pixel[1]);
      else
	memset(pixel[1], 0, 4);

      average_two_pixels (dest, pixel, needx - xi, bpp, param->has_alpha);
    } /* antialias */

  else
    {
      if (xi >=0 && xi < width)
	gimp_pixel_fetcher_get_pixel (pft, xi, y, dest);
      else
	memset(dest, 0, bpp);
    }
}
コード例 #2
0
ファイル: spread.c プロジェクト: Minoos/gimp
static void
spread_func (gint      x,
             gint      y,
             guchar   *dest,
             gint      bpp,
             gpointer  data)
{
  SpreadParam_t *param = (SpreadParam_t*) data;
  gdouble        angle;
  gint           xdist, ydist;
  gint           xi, yi;

  /* get random angle, x distance, and y distance */
  xdist = (param->x_amount > 0
           ? g_rand_int_range (param->gr, -param->x_amount, param->x_amount)
           : 0);
  ydist = (param->y_amount > 0
           ? g_rand_int_range (param->gr, -param->y_amount, param->y_amount)
           : 0);
  angle = g_rand_double_range (param->gr, -G_PI, G_PI);

  xi = x + floor (sin (angle) * xdist);
  yi = y + floor (cos (angle) * ydist);

  /* Only displace the pixel if it's within the bounds of the image. */
  if (xi >= 0 && xi < param->width && yi >= 0 && yi < param->height)
    {
      gimp_pixel_fetcher_get_pixel (param->pft, xi, yi, dest);
    }
  else /* Else just copy it */
    {
      gimp_pixel_fetcher_get_pixel (param->pft, x, y, dest);
    }
}
コード例 #3
0
ファイル: ripple.c プロジェクト: Amerekanets/gimp
static void
ripple_vertical (gint x,
                 gint y,
                 guchar *dest,
                 gint bpp,
                 gpointer data)
{
  RippleParam_t *param = (RippleParam_t*) data;
  GimpPixelFetcher *pft;
  guchar   pixel[2][4];
  gdouble  needy;
  gint     yi, yi_a, height;

  pft = param->pft;
  height = param->height;

  needy = y + displace_amount(x);
  yi = floor(needy);
  yi_a = yi+1;

  /* Tile the image. */
  if (rvals.edges == WRAP)
    {
      needy = fmod(needy, height);
      if (needy < 0.0)
	needy += height;
      yi = (yi % height);
      if (yi < 0)
	yi += height;
      yi_a = (yi+1) % height;
    }
  /* Smear out the edges of the image by repeating pixels. */
  else if (rvals.edges == SMEAR)
    {
      needy= CLAMP (needy   , 0, height - 1);
      yi   = CLAMP (yi      , 0, height - 1);
      yi_a = CLAMP (yi_a + 1, 0, height - 1);
    }

  if (rvals.antialias)
    {
      if (yi >=0 && yi < height)
	gimp_pixel_fetcher_get_pixel (pft, x, yi  , pixel[0]);
      else
	memset(pixel[0], 0, 4);
      if (yi_a >=0 && yi_a < height)
	gimp_pixel_fetcher_get_pixel (pft, x, yi_a, pixel[1]);
      else
	memset(pixel[1], 0, 4);

      average_two_pixels (dest, pixel, needy - yi, bpp, param->has_alpha);
    } /* antialias */
  else
    {
      if (yi >=0 && yi < height)
	gimp_pixel_fetcher_get_pixel (pft, x, yi, dest);
      else
	memset(dest, 0, bpp);
    }
}
コード例 #4
0
ファイル: pygimp-tile.c プロジェクト: jdburton/gimp-osx
static PyObject *
pf_subscript(PyGimpPixelFetcher *self, PyObject *key)
{
    PyObject *py_x, *py_y;
    int x, y;
    guchar pixel[4];

    if (!PyTuple_Check(key) || PyTuple_Size(key) != 2) {
        PyErr_SetString(PyExc_TypeError, "subscript must be a 2-tuple");
	return NULL;
    }

    if (!PyArg_ParseTuple(key, "OO", &py_x, &py_y))
        return NULL;

    if (PyInt_Check(py_x)) {
        if (PyInt_Check(py_y)) {
	    x = PyInt_AsLong(py_x);
            y = PyInt_AsLong(py_y);

            gimp_pixel_fetcher_get_pixel(self->pf, x, y, pixel);
            return PyString_FromStringAndSize((char *)pixel, self->bpp);
        } else {
            PyErr_SetString(PyExc_TypeError, "invalid y subscript");
            return NULL;
        }
    } else {
        PyErr_SetString(PyExc_TypeError, "invalid x subscript");
        return NULL;
    }
}
コード例 #5
0
ファイル: gap_morph_shape.c プロジェクト: nhorman/gimp-gap
/* -----------------------------
 * p_pixel_check_opaque
 * -----------------------------
 * check average opacity in an area
 * of 2x2 pixels
 * return TRUE if average alpha is 50% or more opaque
 */
static gboolean
p_pixel_check_opaque(GimpPixelFetcher *pft, gint bpp, gdouble needx, gdouble needy)
{
  guchar  pixel[4][4];
  gdouble alpha_val;

  gint    xi, yi;
  gint alpha_idx;


  if (needx >= 0.0)
    xi = (int) needx;
  else
    xi = -((int) -needx + 1);

  if (needy >= 0.0)
    yi = (int) needy;
  else
    yi = -((int) -needy + 1);

  gimp_pixel_fetcher_get_pixel (pft, xi, yi, pixel[0]);
  gimp_pixel_fetcher_get_pixel (pft, xi + 1, yi, pixel[1]);
  gimp_pixel_fetcher_get_pixel (pft, xi, yi + 1, pixel[2]);
  gimp_pixel_fetcher_get_pixel (pft, xi + 1, yi + 1, pixel[3]);

  alpha_idx = bpp -1;
  /* average aplha channel normalized to range 0.0 upto 1.0 */
  alpha_val = (
               (gdouble)pixel[0][alpha_idx] / 255.0
            +  (gdouble)pixel[1][alpha_idx] / 255.0
            +  (gdouble)pixel[2][alpha_idx] / 255.0
            +  (gdouble)pixel[3][alpha_idx] / 255.0
            ) /  4.0;

  if (alpha_val > 0.5)  /* fix THRESHOLD half or more opaque */
  {
    return (TRUE);
  }
  return (FALSE);
}  /* end p_pixel_check_opaque */
コード例 #6
0
ファイル: lens-distortion.c プロジェクト: AjayRamanathan/gimp
static void
lens_distort_func (gint              ix,
                   gint              iy,
                   guchar           *dest,
                   gint              bpp,
                   GimpPixelFetcher *pft)
{
  gdouble  src_x, src_y, mag;
  gdouble  brighten;
  guchar   pixel_buffer[16 * LENS_MAX_PIXEL_DEPTH];
  guchar  *pixel;
  gdouble  dx, dy;
  gint     x_int, y_int;
  gint     x, y;

  lens_get_source_coords (ix, iy, &src_x, &src_y, &mag);

  brighten = 1.0 + mag * calc_vals.brighten;
  x_int = floor (src_x);
  dx = src_x - x_int;

  y_int = floor (src_y);
  dy = src_y - y_int;

  pixel = pixel_buffer;
  for (y = y_int - 1; y <= y_int + 2; y++)
    {
      for (x = x_int -1; x <= x_int + 2; x++)
        {
          if (x >= 0  && y >= 0 &&
              x < drawable_width &&  y < drawable_height)
            {
              gimp_pixel_fetcher_get_pixel (pft, x, y, pixel);
            }
          else
            {
              gint i;

              for (i = 0; i < bpp; i++)
                pixel[i] = background_color[i];
            }

          pixel += bpp;
        }
    }

  lens_cubic_interpolate (pixel_buffer, bpp * 4, bpp,
                          dest, bpp, dx, dy, brighten);
}
コード例 #7
0
ファイル: polar.c プロジェクト: Amerekanets/gimp
static void
polarize_func (gint x,
               gint y,
               guchar *dest,
               gint bpp,
               gpointer data)
{
  double     cx, cy;

  if (calc_undistorted_coords (x, y, &cx, &cy))
    {
      guchar     pixel1[4], pixel2[4], pixel3[4], pixel4[4];
      guchar     *values[4];
      GimpPixelFetcher *pft = (GimpPixelFetcher*) data;

      values[0] = pixel1;
      values[1] = pixel2;
      values[2] = pixel3;
      values[3] = pixel4;

      gimp_pixel_fetcher_get_pixel (pft, cx, cy, pixel1);
      gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy, pixel2);
      gimp_pixel_fetcher_get_pixel (pft, cx, cy + 1, pixel3);
      gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy + 1, pixel4);

      gimp_bilinear_pixels_8 (dest, cx, cy, bpp, img_has_alpha, values);
    }
  else
    {
      gint b;
      for (b = 0; b < bpp; b++)
        {
          dest[b] = back_color[b];
        }
    }
}
コード例 #8
0
ファイル: pygimp-tile.c プロジェクト: jdburton/gimp-osx
static PyObject *
pf_get_pixel(PyGimpPixelFetcher *self, PyObject *args, PyObject *kwargs)
{
    int x, y;
    guchar pixel[4];
    static char *kwlist[] = { "x", "y", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "ii:get_pixel", kwlist,
                                      &x, &y))
        return NULL;

    gimp_pixel_fetcher_get_pixel(self->pf, x, y, pixel);

    return PyString_FromStringAndSize((char *)pixel, self->bpp);
}
コード例 #9
0
ファイル: mblur.c プロジェクト: Amerekanets/gimp
static void
mblur_linear (GimpDrawable *drawable,
              GimpPreview  *preview,
              gint          x1,
              gint          y1,
              gint          width,
              gint          height)
{
  GimpPixelRgn      dest_rgn;
  GimpPixelFetcher *pft;
  gpointer          pr;
  GimpRGB           background;

  guchar *dest;
  guchar *d;
  guchar  pixel[4];
  gint32  sum[4];
  gint    progress, max_progress;
  gint    c, p;
  gint    x, y, i, xx, yy, n;
  gint    dx, dy, px, py, swapdir, err, e, s1, s2;

  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_pixel_fetcher_set_bg_color (pft, &background);

  progress     = 0;
  max_progress = width * height;

  n = mbvals.length;
  px = (gdouble) n * cos (mbvals.angle / 180.0 * G_PI);
  py = (gdouble) n * sin (mbvals.angle / 180.0 * G_PI);

  /*
   * Initialization for Bresenham algorithm:
   * dx = abs(x2-x1), s1 = sign(x2-x1)
   * dy = abs(y2-y1), s2 = sign(y2-y1)
   */
  if ((dx = px) != 0)
    {
      if (dx < 0)
        {
          dx = -dx;
          s1 = -1;
        }
      else
        s1 = 1;
    }
  else
    s1 = 0;

  if ((dy = py) != 0)
    {
      if (dy < 0)
        {
          dy = -dy;
          s2 = -1;
        }
      else
        s2 = 1;
    }
  else
    s2 = 0;

  if (dy > dx)
    {
      swapdir = dx;
      dx = dy;
      dy = swapdir;
      swapdir = 1;
    }
  else
    swapdir = 0;

  dy *= 2;
  err = dy - dx;        /* Initial error term   */
  dx *= 2;

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn), p = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), p++)
    {
      dest = dest_rgn.data;

      for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
        {
          d = dest;

          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              xx = x; yy = y; e = err;
              for (c = 0; c < img_bpp; c++)
                sum[c]= 0;

              for (i = 0; i < n; )
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, pixel);

                  if (has_alpha)
                    {
                      gint32 alpha = pixel[img_bpp-1];

                      sum[img_bpp-1] += alpha;
                      for (c = 0; c < img_bpp-1; c++)
                        sum[c] += pixel[c] * alpha;
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        sum[c] += pixel[c];
                    }
                  i++;

                  while (e >= 0 && dx)
                    {
                      if (swapdir)
                        xx += s1;
                      else
                        yy += s2;
                      e -= dx;
                    }

                  if (swapdir)
                    yy += s2;
                  else
                    xx += s1;

                  e += dy;

                  if ((xx < x1) || (xx >= x1 + width) ||
                      (yy < y1) || (yy >= y1 + height))
                    break;
                }

              if (i == 0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, d);
                }
              else
                {
                  if (has_alpha)
                    {
                      gint32 alpha = sum[img_bpp-1];

                      if ((d[img_bpp-1] = alpha/i) != 0)
                        {
                          for (c = 0; c < img_bpp-1; c++)
                            d[c] = sum[c] / alpha;
                        }
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        d[c] = sum[c] / i;
                    }
                }

              d += dest_rgn.bpp;
            }

          dest += dest_rgn.rowstride;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;

          if ((p % 8) == 0)
            gimp_progress_update ((gdouble) progress / max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);
}
コード例 #10
0
ファイル: polar.c プロジェクト: Amerekanets/gimp
static void
dialog_update_preview (GimpDrawable *drawable,
                       GimpPreview  *preview)
{
  gdouble               cx, cy;
  gint                  x, y;
  gint                  sx, sy;
  gint                  width, height;
  guchar               *pixel;
  guchar                outside[4];
  GimpRGB               background;
  guchar               *dest;
  gint                  j;
  gint                  bpp;
  GimpPixelFetcher     *pft;
  guchar                in_pixels[4][4];
  guchar               *in_values[4];

  for (j = 0; j < 4; j++)
    in_values[j] = in_pixels[j];

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_rgb_set_alpha (&background, 0.0);
  gimp_drawable_get_color_uchar (drawable->drawable_id, &background, outside);
  gimp_pixel_fetcher_set_bg_color (pft, &background);
  gimp_pixel_fetcher_set_edge_mode (pft, GIMP_PIXEL_FETCHER_EDGE_SMEAR);

  dest = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
                                       &width, &height, &bpp);
  pixel = dest;

  for (y = 0; y < height; y++)
    {
      for (x = 0; x < width; x++)
        {
          gimp_preview_untransform (preview, x, y, &sx, &sy);
          if (calc_undistorted_coords ((gdouble)sx, (gdouble)sy,
                                       &cx, &cy))
            {

              gimp_pixel_fetcher_get_pixel (pft, cx, cy, in_pixels[0]);
              gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy, in_pixels[1]);
              gimp_pixel_fetcher_get_pixel (pft, cx, cy + 1, in_pixels[2]);
              gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy + 1, in_pixels[3]);

              gimp_bilinear_pixels_8 (pixel, cx, cy, bpp,
                                      img_has_alpha, in_values);
            }
          else
            {
              for (j = 0; j < bpp; j++)
                pixel[j] = outside[j];
            }

          pixel += bpp;
        }
    }

  gimp_pixel_fetcher_destroy (pft);

  gimp_preview_draw_buffer (preview, dest, width * bpp);
  g_free (dest);
}
コード例 #11
0
ファイル: edge.c プロジェクト: WilfR/Gimp-Matting
static void
edge (GimpDrawable *drawable)
{
  GimpPixelRgn      src_rgn, dest_rgn;
  gpointer          pr;
  GimpPixelFetcher *pft;
  guchar           *srcrow, *src;
  guchar           *destrow, *dest;
  guchar            pix00[4], pix01[4], pix02[4];
  guchar            pix10[4], pix11[4], pix12[4];
  guchar            pix20[4], pix21[4], pix22[4];
  glong             width, height;
  gint              alpha;
  gboolean          has_alpha;
  gint              chan;
  gint              x, y;
  gint              x1, y1, x2, y2;
  gint              maxval;
  gint              cur_progress;
  gint              max_progress;
  gdouble           per_progress;

  if (evals.amount < 1.0)
    evals.amount = 1.0;

  pft = gimp_pixel_fetcher_new (drawable, FALSE);
  gimp_pixel_fetcher_set_edge_mode (pft, evals.wrapmode);

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  width     = gimp_drawable_width (drawable->drawable_id);
  height    = gimp_drawable_height (drawable->drawable_id);
  alpha     = gimp_drawable_bpp (drawable->drawable_id);
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  if (has_alpha)
    alpha--;

  maxval = 255;

  cur_progress = 0;
  per_progress = 0.0;
  max_progress = (x2 - x1) * (y2 - y1) / 100;

  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, x2-x1, y2-y1, FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2-x1, y2-y1, TRUE, TRUE);

  for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      srcrow  = src_rgn.data;
      destrow = dest_rgn.data;

      for (y = dest_rgn.y;
           y < (dest_rgn.y + dest_rgn.h);
           y++, srcrow += src_rgn.rowstride, destrow += dest_rgn.rowstride)
        {
          src  = srcrow;
          dest = destrow;

          for (x = dest_rgn.x;
               x < (dest_rgn.x + dest_rgn.w);
               x++,  src += src_rgn.bpp, dest += dest_rgn.bpp)
            {
              if (dest_rgn.x < x &&  x < dest_rgn.x + dest_rgn.w - 2 &&
                  dest_rgn.y < y &&  y < dest_rgn.y + dest_rgn.h - 2)
                {
                  /*
                   * 3x3 kernel is inside of the tile -- do fast
                   * version
                   */
                  for (chan = 0; chan < alpha; chan++)
                    {
                      /* get the 3x3 kernel into a guchar array,
                       * and send it to edge_detect */
                      guchar kernel[9];
                      gint   i,j;

#define PIX(X,Y)  src[ (Y-1)*(int)src_rgn.rowstride + (X-1)*(int)src_rgn.bpp + chan ]
                      /* make convolution */
                      for(i = 0; i < 3; i++)
                        for(j = 0; j < 3; j++)
                          kernel[3*i + j] = PIX(i,j);

#undef  PIX

                      dest[chan] = edge_detect (kernel);
                    }
                }
              else
                {
                  /*
                   * The kernel is not inside of the tile -- do slow
                   * version
                   */

                  gimp_pixel_fetcher_get_pixel (pft, x-1, y-1, pix00);
                  gimp_pixel_fetcher_get_pixel (pft, x  , y-1, pix10);
                  gimp_pixel_fetcher_get_pixel (pft, x+1, y-1, pix20);
                  gimp_pixel_fetcher_get_pixel (pft, x-1, y  , pix01);
                  gimp_pixel_fetcher_get_pixel (pft, x  , y  , pix11);
                  gimp_pixel_fetcher_get_pixel (pft, x+1, y  , pix21);
                  gimp_pixel_fetcher_get_pixel (pft, x-1, y+1, pix02);
                  gimp_pixel_fetcher_get_pixel (pft, x  , y+1, pix12);
                  gimp_pixel_fetcher_get_pixel (pft, x+1, y+1, pix22);

                  for (chan = 0; chan < alpha; chan++)
                    {
                      guchar kernel[9];

                      kernel[0] = pix00[chan];
                      kernel[1] = pix01[chan];
                      kernel[2] = pix02[chan];
                      kernel[3] = pix10[chan];
                      kernel[4] = pix11[chan];
                      kernel[5] = pix12[chan];
                      kernel[6] = pix20[chan];
                      kernel[7] = pix21[chan];
                      kernel[8] = pix22[chan];

                      dest[chan] = edge_detect (kernel);
                    }
                }
              if (has_alpha)
                dest[alpha] = src[alpha];
            }
        }
      cur_progress += dest_rgn.w * dest_rgn.h;

      if (cur_progress > max_progress)
        {
          cur_progress = cur_progress - max_progress;
          per_progress = per_progress + 0.01;
          gimp_progress_update (per_progress);
        }
    }

  gimp_progress_update (1.0);

  gimp_pixel_fetcher_destroy (pft);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));
}
コード例 #12
0
ファイル: displace.c プロジェクト: MichaelMure/Gimp-Cage-Tool
static void
displace (GimpDrawable *drawable,
          GimpPreview  *preview)
{
  GimpDrawable     *map_x = NULL;
  GimpDrawable     *map_y = NULL;
  GimpPixelRgn      dest_rgn;
  GimpPixelRgn      map_x_rgn;
  GimpPixelRgn      map_y_rgn;
  gpointer          pr;
  GimpPixelFetcher *pft;

  gint              width;
  gint              height;
  gint              bytes;
  guchar           *destrow, *dest;
  guchar           *mxrow, *mx;
  guchar           *myrow, *my;
  guchar            pixel[4][4];
  gint              x1, y1, x2, y2;
  gint              x, y;
  gdouble           cx, cy;
  gint              progress, max_progress;

  gdouble           amnt;
  gdouble           needx, needy;
  gdouble           radius, d_alpha;
  gint              xi, yi;

  guchar            values[4];
  guchar            val;

  gint              k;

  gdouble           xm_val, ym_val;
  gint              xm_alpha = 0;
  gint              ym_alpha = 0;
  gint              xm_bytes = 1;
  gint              ym_bytes = 1;
  guchar           *buffer   = NULL;
  gdouble           pi;

  /* initialize */

  /* get rid of uninitialized warnings */
  cx = cy = needx = needy = radius = d_alpha = 0.0;

  pi = 4 * atan (1);

  mxrow = NULL;
  myrow = NULL;

  pft = gimp_pixel_fetcher_new (drawable, FALSE);
  gimp_pixel_fetcher_set_edge_mode (pft, dvals.displace_type);

  bytes  = drawable->bpp;

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
  width  = x2 - x1;
  height = y2 - y1;

  if (dvals.mode == POLAR_MODE)
    {
      cx = x1 + width / 2.0;
      cy = y1 + height / 2.0;
    }

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
      x2 = x1 + width;
      y2 = y1 + height;
      buffer = g_new (guchar, width * height * bytes);
    }

  progress     = 0;
  max_progress = width * height;

  /*
   * The algorithm used here is simple - see
   * http://the-tech.mit.edu/KPT/Tips/KPT7/KPT7.html for a description.
   */

  /* Get the drawables  */
  if (dvals.displace_map_x != -1 && dvals.do_x)
    {
      map_x = gimp_drawable_get (dvals.displace_map_x);
      gimp_pixel_rgn_init (&map_x_rgn, map_x,
                           x1, y1, width, height, FALSE, FALSE);

      if (gimp_drawable_has_alpha (map_x->drawable_id))
        xm_alpha = 1;

      xm_bytes = gimp_drawable_bpp (map_x->drawable_id);
    }

  if (dvals.displace_map_y != -1 && dvals.do_y)
    {
      map_y = gimp_drawable_get (dvals.displace_map_y);
      gimp_pixel_rgn_init (&map_y_rgn, map_y,
                           x1, y1, width, height, FALSE, FALSE);

      if (gimp_drawable_has_alpha (map_y->drawable_id))
        ym_alpha = 1;

      ym_bytes = gimp_drawable_bpp (map_y->drawable_id);
    }

  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height,
                       preview == NULL, preview == NULL);

  /*  Register the pixel regions  */
  if (dvals.do_x && dvals.do_y)
    pr = gimp_pixel_rgns_register (3, &dest_rgn, &map_x_rgn, &map_y_rgn);
  else if (dvals.do_x)
    pr = gimp_pixel_rgns_register (2, &dest_rgn, &map_x_rgn);
  else if (dvals.do_y)
    pr = gimp_pixel_rgns_register (2, &dest_rgn, &map_y_rgn);
  else
    pr = NULL;

  for (pr = pr; pr != NULL; pr = gimp_pixel_rgns_process (pr))
    {
      destrow = dest_rgn.data;
      if (dvals.do_x)
        mxrow = map_x_rgn.data;
      if (dvals.do_y)
        myrow = map_y_rgn.data;

      for (y = dest_rgn.y; y < (dest_rgn.y + dest_rgn.h); y++)
        {
          if (preview)
            dest = buffer + ((y - y1) * width + (dest_rgn.x - x1)) * bytes;
          else
            dest = destrow;
          mx = mxrow;
          my = myrow;

          /*
           * We could move the displacement image address calculation
           * out of here, but when we can have different sized
           * displacement and destination images we'd have to move it
           * back anyway.
           */

          for (x = dest_rgn.x; x < (dest_rgn.x + dest_rgn.w); x++)
            {
              if (dvals.do_x)
                {
                  xm_val = displace_map_give_value(mx, xm_alpha, xm_bytes);
                  amnt = dvals.amount_x * (xm_val - 127.5) / 127.5;
                  /* CARTESIAN_MODE == 0 - performance important here */
                  if (! dvals.mode)
                    {
                      needx = x + amnt;
                    }
                  else
                    {
                      radius = sqrt (SQR (x - cx) + SQR (y - cy)) + amnt;
                    }
                  mx += xm_bytes;
                }
              else
                {
                  if (! dvals.mode)
                    needx = x;
                  else
                    radius = sqrt ((x - cx) * (x - cx) + (y - cy) * (y - cy));
                }


              if (dvals.do_y)
                {
                  ym_val = displace_map_give_value(my, ym_alpha, ym_bytes);
                  amnt = dvals.amount_y * (ym_val - 127.5) / 127.5;
                  if (! dvals.mode)
                    {
                      needy = y + amnt;
                    }
                  else
                    {
                      d_alpha = atan2 (x - cx, y - cy) + (dvals.amount_y / 180)
                                * pi * (ym_val - 127.5) / 127.5;
                    }
                  my += ym_bytes;
                }
              else
                {
                  if (! dvals.mode)
                    needy = y;
                  else
                    d_alpha = atan2 (x - cx, y - cy);
                }
              if (dvals.mode)
                {
                   needx = cx + radius * sin (d_alpha);
                   needy = cy + radius * cos (d_alpha);
                }
              /* Calculations complete; now copy the proper pixel */

              if (needx >= 0.0)
                xi = (int) needx;
              else
                xi = -((int) -needx + 1);

              if (needy >= 0.0)
                yi = (int) needy;
              else
                yi = -((int) -needy + 1);

              gimp_pixel_fetcher_get_pixel (pft, xi, yi, pixel[0]);
              gimp_pixel_fetcher_get_pixel (pft, xi + 1, yi, pixel[1]);
              gimp_pixel_fetcher_get_pixel (pft, xi, yi + 1, pixel[2]);
              gimp_pixel_fetcher_get_pixel (pft, xi + 1, yi + 1, pixel[3]);

              for (k = 0; k < bytes; k++)
                {
                  values[0] = pixel[0][k];
                  values[1] = pixel[1][k];
                  values[2] = pixel[2][k];
                  values[3] = pixel[3][k];
                  val = gimp_bilinear_8 (needx, needy, values);

                  *dest++ = val;
                } /* for */
            }

          destrow += dest_rgn.rowstride;

          if (dvals.do_x)
            mxrow += map_x_rgn.rowstride;
          if (dvals.do_y)
            myrow += map_y_rgn.rowstride;
        }

      if (!preview)
        {
          progress += dest_rgn.w * dest_rgn.h;
          gimp_progress_update ((double) progress / (double) max_progress);
        }
    } /* for */

  gimp_pixel_fetcher_destroy (pft);

  /*  detach from the map drawables  */
  if (dvals.do_x)
    gimp_drawable_detach (map_x);
  if (dvals.do_y)
    gimp_drawable_detach (map_y);

  if (preview)
    {
/*      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &dest_rgn);*/
      gimp_preview_draw_buffer (preview, buffer, width * bytes);
      g_free (buffer);
    }
  else
    {
      /*  update the region  */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }
}
コード例 #13
0
ファイル: shift.c プロジェクト: WilfR/Gimp-Matting
static void
shift (GimpDrawable *drawable,
       GimpPreview  *preview)
{
  GimpPixelRgn      dest_rgn;
  gpointer          pr;
  GimpPixelFetcher *pft;
  gint              width, height;
  gint              bytes;
  guchar           *destline;
  guchar           *dest;
  gint              x1, y1, x2, y2;
  gint              x, y;
  gint              progress, max_progress;
  gint              i, n = 0;
  gint             *offsets;
  GRand            *gr;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
      width  = x2 - x1;
      height = y2 - y1;
    }

  bytes  = drawable->bpp;

  progress     = 0;
  max_progress = width * height;

  /* Shift the image.  It's a pretty simple algorithm.  If horizontal
     is selected, then every row is shifted a random number of pixels
     in the range of -shift_amount/2 to shift_amount/2.  The effect is
     just reproduced with columns if vertical is selected.
   */

  n = (shvals.orientation == HORIZONTAL) ? height : width;

  offsets = g_new (gint, n);
  gr = g_rand_new ();

  for (i = 0; i < n; i++)
    offsets[i] = g_rand_int_range (gr,
                                   - (shvals.shift_amount + 1) / 2.0,
                                   + (shvals.shift_amount + 1) / 2.0);

  g_rand_free (gr);

  pft = gimp_pixel_fetcher_new (drawable, FALSE);
  gimp_pixel_fetcher_set_edge_mode (pft, GIMP_PIXEL_FETCHER_EDGE_WRAP);

  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      destline = dest_rgn.data;

      switch (shvals.orientation)
        {
        case HORIZONTAL:
          for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
            {
              dest = destline;

              for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
                {
                  gimp_pixel_fetcher_get_pixel (pft,
                                                x + offsets[y - y1], y, dest);
                  dest += bytes;
                }

              destline += dest_rgn.rowstride;
            }
          break;

        case VERTICAL:
          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              dest = destline;

              for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
                {
                  gimp_pixel_fetcher_get_pixel (pft,
                                                x, y + offsets[x - x1], dest);
                  dest += dest_rgn.rowstride;
                }

              destline += bytes;
            }
          break;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;
          gimp_progress_update ((double) progress / (double) max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);
  g_free (offsets);

  if (! preview)
    {
      gimp_progress_update (1.0);
      /*  update the region  */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }
}
コード例 #14
0
ファイル: gap_morph_shape.c プロジェクト: nhorman/gimp-gap
/* --------------------------------
 * p_generateWorkpoints
 * --------------------------------
 * scan the edge drawable with descending grid size (defined stepSizeTab)
 * and descending edge threshold. This shall spread the generated
 * workpoints all over the whole area where bright edge points
 * are picked first.
 */
static void
p_generateWorkpoints(GapMorphShapeContext *msctx, GapMorphGlobalParams *mgpp)
{
#define LOOP_LOOKUP_TAB_SIZE 5
  static gint32  edgeThresTab[LOOP_LOOKUP_TAB_SIZE]   = { 120, 60, 30, 10,  1 };
  static gint32  nearRadiusTab[LOOP_LOOKUP_TAB_SIZE]  = {  20, 14, 10,  6,  2 };
  static gint32  stepSizeTab[LOOP_LOOKUP_TAB_SIZE]    = {  10,  8,  6,  2,  1 };
  gint32  ex;
  gint32  ey;
  gdouble srcX;
  gdouble srcY;
  gint32  nearRadius;
  gint32  edgePixelThreshold255;
  gint32  stepSize;
  gint32  ii;

  for(ii=0; ii < LOOP_LOOKUP_TAB_SIZE; ii++)
  {
    edgePixelThreshold255 = edgeThresTab[ii];
    nearRadius = nearRadiusTab[ii];
    stepSize = stepSizeTab[ii];
    
    for(ey=msctx->sel1Y; ey < msctx->sel2Y; ey += stepSize)
    {
      srcY = ey +1;
      for(ex=msctx->sel1X; ex < msctx->sel2X; ex += stepSize)
      {
        guchar pixel[4];
  
        if(*msctx->cancelWorkpointGenerationPtr == TRUE)
        {
          return;
        }

        gimp_pixel_fetcher_get_pixel (msctx->pftEdge, ex, ey, &pixel[0]);

        if(pixel[0] >= edgePixelThreshold255)
        {
          /* found an edge pixel */
          GapMorphWorkPoint *wp;

          srcX = ex +1;


          /* chek if workpoint with this (or very near) coords does already exist */
          wp = p_find_workpoint_near_src_coords(mgpp
                      , srcX
                      , srcY
                      , nearRadius
                      );
          if(wp == NULL)
          {
            gboolean success;
            gdouble dstX;
            gdouble dstY;
            gdouble locateColordiff;

            success = p_locate_workpoint(msctx
                                        , srcX,  srcY
                                        , &dstX, &dstY
                                        , &locateColordiff
                                        );
            if(success)
            {
              wp = gap_morph_shape_new_workpont(srcX, srcY, dstX, dstY);
              wp->locateColordiff = locateColordiff;
              
              if(TRUE == p_workpoint_plausiblity_filter(msctx
                    , mgpp
                    , wp
                    ))
              {
                msctx->countGeneratedPoints++; 
                /* add new workpoint as 1st listelement */
                wp->next = mgpp->master_wp_list;
                mgpp->master_wp_list = wp;

                p_doProgress(msctx);

                if(msctx->countGeneratedPoints >= msctx->numShapePoints)
                {
                  return;
                }
              }
              else
              {
                g_free(wp);
              }

            }

          }

        }

      }
    }
  }
  
}  /* end p_generateWorkpoints */
コード例 #15
0
ファイル: mblur.c プロジェクト: Amerekanets/gimp
static void
mblur_radial (GimpDrawable *drawable,
              GimpPreview  *preview,
              gint          x1,
              gint          y1,
              gint          width,
              gint          height)
{
  GimpPixelRgn      dest_rgn;
  GimpPixelFetcher *pft;
  gpointer          pr;
  GimpRGB           background;

  gdouble   center_x;
  gdouble   center_y;
  guchar   *dest;
  guchar   *d;
  guchar    pixel[4];
  guchar    p1[4], p2[4], p3[4], p4[4];
  gint32    sum[4];

  gint      progress, max_progress, c;

  gint      x, y, i, p, n, count;
  gdouble   angle, theta, r, xx, yy, xr, yr;
  gdouble   phi, phi_start, s_val, c_val;
  gdouble   dx, dy;

  /* initialize */

  xx = 0.0;
  yy = 0.0;

  center_x = mbvals.center_x;
  center_y = mbvals.center_y;

  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_pixel_fetcher_set_bg_color (pft, &background);

  progress     = 0;
  max_progress = width * height;

  angle = gimp_deg_to_rad (mbvals.angle);

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn), p = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), p++)
    {
      dest = dest_rgn.data;

      for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
        {
          d = dest;

          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              xr = (gdouble) x - center_x;
              yr = (gdouble) y - center_y;

              r = sqrt (SQR (xr) + SQR (yr));
              n = r * angle;

              if (angle == 0.0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, x, y, d);
                  d += dest_rgn.bpp;
                  continue;
                }

              /* ensure quality with small angles */
              if (n < 3)
                n = 3;  /* always use at least 3 (interpolation) steps */

              /* limit loop count due to performanc reasons */
              if (n > 100)
                n = 100 + sqrt (n-100);

              if (xr != 0.0)
                {
                  phi = atan(yr/xr);
                  if (xr < 0.0)
                    phi = G_PI + phi;

                }
              else
                {
                  if (yr >= 0.0)
                    phi = G_PI_2;
                  else
                    phi = -G_PI_2;
                }

              for (c = 0; c < img_bpp; c++)
                sum[c] = 0;

              if (n == 1)
                phi_start = phi;
              else
                phi_start = phi + angle/2.0;

              theta = angle / (gdouble)n;
              count = 0;

              for (i = 0; i < n; i++)
                {
                  s_val = sin (phi_start - (gdouble) i * theta);
                  c_val = cos (phi_start - (gdouble) i * theta);

                  xx = center_x + r * c_val;
                  yy = center_y + r * s_val;

                  if ((yy < y1) || (yy >= y1 + height) ||
                      (xx < x1) || (xx >= x1 + width))
                    continue;

                  ++count;
                  if ((xx + 1 < x1 + width) && (yy + 1 < y1 + height))
                    {
                      dx = xx - floor (xx);
                      dy = yy - floor (yy);

                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy,   p1);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy,   p2);
                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy+1, p3);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy+1, p4);

                      for (c = 0; c < img_bpp; c++)
                        {
                          pixel[c] = (((gdouble) p1[c] * (1.0-dx) +
                                       (gdouble) p2[c] * dx) * (1.0-dy) +
                                      ((gdouble) p3[c] * (1.0-dx) +
                                       (gdouble) p4[c] * dx) * dy);
                        }
                    }
                  else
                    {
                      gimp_pixel_fetcher_get_pixel (pft, xx+.5, yy+.5, pixel);
                    }

                  if (has_alpha)
                    {
                      gint32 alpha = pixel[img_bpp-1];

                      sum[img_bpp-1] += alpha;

                      for (c = 0; c < img_bpp-1; c++)
                        sum[c] += pixel[c] * alpha;
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        sum[c] += pixel[c];
                    }
                }

              if (count == 0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, d);
                }
              else
                {
                  if (has_alpha)
                    {
                      gint32 alpha = sum[img_bpp-1];

                      if ((d[img_bpp-1] = alpha/count) != 0)
                        {
                          for (c = 0; c < img_bpp-1; c++)
                            d[c] = sum[c] / alpha;
                        }
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        d[c] = sum[c] / count;
                    }
                }

              d += dest_rgn.bpp;
            }

          dest += dest_rgn.rowstride;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;

          if ((p % 8) == 0)
            gimp_progress_update ((gdouble) progress / max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);

}
コード例 #16
0
ファイル: mblur.c プロジェクト: Amerekanets/gimp
static void
mblur_zoom (GimpDrawable *drawable,
            GimpPreview  *preview,
            gint          x1,
            gint          y1,
            gint          width,
            gint          height)
{
  GimpPixelRgn      dest_rgn;
  GimpPixelFetcher *pft;
  gpointer          pr;
  GimpRGB           background;

  gdouble   center_x;
  gdouble   center_y;
  guchar   *dest, *d;
  guchar    pixel[4];
  guchar    p1[4], p2[4], p3[4], p4[4];
  gint32    sum[4];

  gint      progress, max_progress;
  gint      x, y, i, n, p, c;
  gdouble   xx_start, xx_end, yy_start, yy_end;
  gdouble   xx, yy;
  gdouble   dxx, dyy;
  gdouble   dx, dy;
  gint      xy_len;
  gdouble   f, r;
  gint      drawable_x1, drawable_y1;
  gint      drawable_x2, drawable_y2;

  /* initialize */

  xx = 0.0;
  yy = 0.0;
  center_x = mbvals.center_x;
  center_y = mbvals.center_y;

  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &drawable_x1, &drawable_y1,
                             &drawable_x2, &drawable_y2);
  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  pft = gimp_pixel_fetcher_new (drawable, FALSE);

  gimp_context_get_background (&background);
  gimp_pixel_fetcher_set_bg_color (pft, &background);

  progress     = 0;
  max_progress = width * height;

  n = mbvals.length;

  if (n == 0)
    n = 1;

  r = sqrt (SQR (drawable->width / 2) + SQR (drawable->height / 2));
  n = ((gdouble) n * r / MBLUR_LENGTH_MAX);
  f = (r-n)/r;

  for (pr = gimp_pixel_rgns_register (1, &dest_rgn), p = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), p++)
    {
      dest = dest_rgn.data;

      for (y = dest_rgn.y; y < dest_rgn.y + dest_rgn.h; y++)
        {
          d = dest;

          for (x = dest_rgn.x; x < dest_rgn.x + dest_rgn.w; x++)
            {
              for (c = 0; c < img_bpp; c++)
                sum[c] = 0;

              xx_start = x;
              yy_start = y;

              if (mbvals.blur_outward)
                {
                  xx_end = center_x + ((gdouble) x - center_x) * f;
                  yy_end = center_y + ((gdouble) y - center_y) * f;
                }
              else
                {
                  xx_end = center_x + ((gdouble) x - center_x) * (1.0/f);
                  yy_end = center_y + ((gdouble) y - center_y) * (1.0/f);
                }

              xy_len = sqrt (SQR (xx_end-xx_start) + SQR (yy_end-yy_start)) + 1;

              if (xy_len < 3)
                xy_len = 3;

              dxx = (xx_end - xx_start) / (gdouble) xy_len;
              dyy = (yy_end - yy_start) / (gdouble) xy_len;

              xx = xx_start;
              yy = yy_start;

              for (i = 0; i < xy_len; i++)
                {
                  if ((yy < drawable_y1) || (yy >= drawable_y2) ||
                      (xx < drawable_x1) || (xx >= drawable_x2))
                    break;

                  if ((xx+1 < drawable_x2) && (yy+1 < drawable_y2))
                    {
                      dx = xx - floor (xx);
                      dy = yy - floor (yy);

                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy,   p1);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy,   p2);
                      gimp_pixel_fetcher_get_pixel (pft, xx,   yy+1, p3);
                      gimp_pixel_fetcher_get_pixel (pft, xx+1, yy+1, p4);

                      for (c = 0; c < img_bpp; c++)
                        {
                          pixel[c] = (((gdouble)p1[c] * (1.0-dx) +
                                       (gdouble)p2[c] * dx) * (1.0-dy) +
                                      ((gdouble)p3[c] * (1.0-dx) +
                                       (gdouble)p4[c] * dx) * dy);
                        }
                    }
                  else
                    {
                      gimp_pixel_fetcher_get_pixel (pft, xx+.5, yy+.5, pixel);
                    }

                  if (has_alpha)
                    {
                      gint32 alpha = pixel[img_bpp-1];

                      sum[img_bpp-1] += alpha;

                      for (c = 0; c < img_bpp-1; c++)
                        sum[c] += pixel[c] * alpha;
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        sum[c] += pixel[c];
                    }

                  xx += dxx;
                  yy += dyy;
                }

              if (i == 0)
                {
                  gimp_pixel_fetcher_get_pixel (pft, xx, yy, d);
                }
              else
                {
                  if (has_alpha)
                    {
                      gint32 alpha = sum[img_bpp-1];

                      if ((d[img_bpp-1] = alpha/i) != 0)
                        {
                          for (c = 0; c < img_bpp-1; c++)
                            d[c] = sum[c] / alpha;
                        }
                    }
                  else
                    {
                      for (c = 0; c < img_bpp; c++)
                        d[c] = sum[c] / i;
                    }
                }

              d += dest_rgn.bpp;
            }

          dest += dest_rgn.rowstride;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += dest_rgn.w * dest_rgn.h;

          if ((p % 8) == 0)
            gimp_progress_update ((gdouble) progress / max_progress);
        }
    }

  gimp_pixel_fetcher_destroy (pft);
}
コード例 #17
0
ファイル: gap_edge_detection.c プロジェクト: nhorman/gimp-gap
/* ---------------------------------
 * p_edgeProcessingForOneRegion
 * ---------------------------------
 * render edge drawable for the current processed pixel region.
 * (use a pixelfetcher on region boundaries)
 */
static void
p_edgeProcessingForOneRegion (const GimpPixelRgn *refPR
                    ,const GimpPixelRgn *edgePR
                    ,GapEdgeContext *ectx)
{
  guint    row;
  guchar* ref = refPR->data;
  guchar* edge = edgePR->data;
  guchar  rightPixel[4];
  guchar  botPixel[4];
  guchar  rbPixel[4];
  guchar* rightPixelPtr;
  guchar* botPixelPtr;
  guchar* rbPixelPtr;
  gint32   rx; 
  gint32   ry; 
  gboolean debugPrint;
        
  
  
  if(gap_debug)
  {
    printf("p_edgeProcessingForOneRegion START\n");
  }
  debugPrint = FALSE;
  
  for (row = 0; row < edgePR->h; row++)
  {
    guint  col;
    guint  idxref;
    guint  idxedge;

    ry = refPR->y + row;

    idxref = 0;
    idxedge = 0;
    for(col = 0; col < edgePR->w; col++)
    {
      gdouble  colordiff1;
      gdouble  colordiff2;
      gdouble  colordiff3;
      gdouble  maxColordiff;
      gboolean isColorCompareRequired;

      rbPixelPtr = &ref[idxref];
      
      rx = refPR->x + col;
      
      isColorCompareRequired = TRUE;
        
/*
 *       if(gap_debug)
 *       {
 *         debugPrint = FALSE;
 *         if((rx == 596) || (rx == 597))
 *         {
 *           if((ry==818) ||(ry==818))
 *           {
 *             debugPrint = TRUE;
 *           }
 *         }
 *       }
 */
      
      if(col < edgePR->w -1)
      {
        rightPixelPtr = &ref[idxref + refPR->bpp];

        if(row < edgePR->h -1)
        {
          rbPixelPtr = &ref[idxref + refPR->bpp + refPR->rowstride];
        }
      }
      else if(rx >= ectx->refDrawable->width -1)
      {
         /* drawable border is not considered as edge */
        rightPixelPtr = &ref[idxref];
      }
      else
      {
        rightPixelPtr = &rightPixel[0];
        gimp_pixel_fetcher_get_pixel (ectx->pftRef, rx +1, ry, rightPixelPtr);

        if(ry >= ectx->refDrawable->height -1)
        {
          rbPixelPtr = &rbPixel[0];
          gimp_pixel_fetcher_get_pixel (ectx->pftRef, rx +1, ry +1, rbPixelPtr);
        }
      }
      
      if(row < edgePR->h -1)
      {
        botPixelPtr = &ref[idxref + refPR->rowstride];
      }
      else if(ry >= ectx->refDrawable->height -1)
      {
         /* drawable border is not considered as edge */
        botPixelPtr = &ref[idxref];
      }
      else
      {
        botPixelPtr = &botPixel[0];
        gimp_pixel_fetcher_get_pixel (ectx->pftRef, rx, ry +1, botPixelPtr);
      }

      if(refPR->bpp > 3)
      {
        /* reference drawable has alpha channel
         * in this case significant changes of opacity shall detect edge
         */
        gint32 maxAlphaDiff;
        
        maxAlphaDiff = MAX(abs(ref[idxref +3] - rightPixelPtr[3])
                          ,abs(ref[idxref +3] - botPixelPtr[3]));
        maxAlphaDiff = MAX(maxAlphaDiff
                          ,abs(ref[idxref +3] - rbPixelPtr[3]));
        if(debugPrint)
        {
          printf("rx:%d ry:%d idxref:%d idxedge:%d (maxAlphaDiff):%d  Thres:%d  Alpha ref:%d right:%d bot:%d rb:%d\n"
               , (int)rx
               , (int)ry
               , (int)idxref
               , (int)idxedge
               , (int)maxAlphaDiff
               , (int)ectx->edgeOpacityThreshold255
               , (int)ref[idxref +3]
               , (int)rightPixelPtr[3]
               , (int)botPixelPtr[3]
               , (int)rbPixelPtr[3]
               );
        }
        
        if(maxAlphaDiff > ectx->edgeOpacityThreshold255)
        {
           ectx->countEdgePixels++;
           edge[idxedge] = maxAlphaDiff;
           isColorCompareRequired = FALSE;
        }
        else if(ref[idxref +3] < OPACITY_LEVEL_UCHAR)
        {
          /* transparent pixel is not considered as edge */
          edge[idxedge] = 0;
          isColorCompareRequired = FALSE;
        }
        
      }
      
      
      if(isColorCompareRequired == TRUE)
      {
        
        colordiff1 = gap_colordiff_simple_guchar(&ref[idxref]
                     , &rightPixelPtr[0]
                     , debugPrint    /* debugPrint */
                     );

        colordiff2 = gap_colordiff_simple_guchar(&ref[idxref]
                     , &botPixelPtr[0]
                     , debugPrint    /* debugPrint */
                     );

        colordiff3 = gap_colordiff_simple_guchar(&ref[idxref]
                     , &rbPixelPtr[0]
                     , debugPrint    /* debugPrint */
                     );
        maxColordiff = MAX(colordiff1, colordiff2);
        maxColordiff = MAX(maxColordiff, colordiff3);

        if(debugPrint)
        {
          printf("rx:%d ry:%d colordiff(1): %.5f (2):%.5f (3):%.5f (max):%.5f Thres:%.5f\n"
            , (int)rx
            , (int)ry
            , (float)colordiff1
            , (float)colordiff2
            , (float)colordiff3
            , (float)maxColordiff
            , (float)ectx->edgeColordiffThreshold
            );
        }

        if (maxColordiff < ectx->edgeColordiffThreshold)
        {
            edge[idxedge] = 0;
        }
        else
        {
            gdouble value;

            value = maxColordiff * 255.0;
            edge[idxedge] = CLAMP(value, 1, 255);
            ectx->countEdgePixels++;
        }
      }
       


      idxref += refPR->bpp;
      idxedge += edgePR->bpp;
    }

    ref += refPR->rowstride;
    edge += edgePR->rowstride;

  }

}  /* end p_edgeProcessingForOneRegion */