コード例 #1
0
ファイル: gimpcolormodule.c プロジェクト: jiapei100/gimp
static PyObject *
pygimp_bilinear(PyObject *self, PyObject *args, PyObject *kwargs)
{
    gdouble x, y;
    gdouble values[4];
    PyObject *py_values;
    static char *kwlist[] = { "x", "y", "values", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "ddO:bilinear", kwlist,
				     &x, &y, &py_values))
  	return NULL;

    if (PyString_Check(py_values)) {
        if (PyString_Size(py_values) == 4) {
            guchar ret;
            ret = gimp_bilinear_8(x, y, (guchar *)PyString_AsString(py_values));
            return PyString_FromStringAndSize((char *)&ret, 1);
        }
    } else if (PySequence_Check(py_values)) {
        if (PySequence_Size(py_values) == 4) {
            int i;
            for (i = 0; i < 4; i++) {
                PyObject *v;
                v = PySequence_GetItem(py_values, i);
                values[i] = PyFloat_AsDouble(v);
                Py_DECREF(v);
            }
            return PyFloat_FromDouble(gimp_bilinear(x, y, values));
        }
    }

    PyErr_SetString(PyExc_TypeError, "values is not a sequence of 4 items");
    return NULL;
}
コード例 #2
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);
    }
}