Esempio n. 1
0
/* FIXME: not 100% bullet proof */
static GeglRectangle
get_required (GeglRectangle       *boundary,
              const GeglRectangle *roi,
              GeglOperation       *operation)
{

  GeglChantO    *o;
  GeglRectangle  area;
  LensValues     lens;
  gdouble        x1, y1, x2, y2, x3, y3, x4, y4, mag;
  gint           x, y, width, height;

  o = GEGL_CHANT_PROPERTIES (operation);

  lens = lens_setup_calc (o, *boundary);

  x = roi->x;
  y = roi->y;
  width = roi->width;
  height = roi->height;

  lens_get_source_coord (x,         y,          &x1, &y1, &mag, &lens);
  lens_get_source_coord (x + width, y,          &x2, &y2, &mag, &lens);
  lens_get_source_coord (x,         y + height, &x3, &y3, &mag, &lens);
  lens_get_source_coord (x + width, y + height, &x4, &y4, &mag, &lens);

  /* This is ugly, and happens
   * with a crazy set of parameters */
  reorder (&x1, &x2);
  reorder (&x3, &x4);

  reorder (&y1, &y3);
  reorder (&y2, &y4);

  if (lens.centre_y > y && lens.centre_y < y + height)
    {
      gdouble x5, y5, x6, y6;

      lens_get_source_coord (x,         lens.centre_y, &x5, &y5, &mag, &lens);
      lens_get_source_coord (x + width, lens.centre_y, &x6, &y6, &mag, &lens);

      reorder (&x5, &x6);

      area.x = floor (MIN3 (x1, x3, x5)) - 1;
      area.width = ceil (MAX3 (x2, x4, x6)) + 3 - area.x;
    }
  else
    {
      area.x = floor (MIN (x1, x3)) - 1;
      area.width = ceil (MAX (x2, x4)) + 3 - area.x;
    }

  if (lens.centre_x > x && lens.centre_x < x + width)
    {
      gdouble x5, y5, x6, y6;

      lens_get_source_coord (lens.centre_x, y,          &x5, &y5, &mag, &lens);
      lens_get_source_coord (lens.centre_x, y + height, &x6, &y6, &mag, &lens);

      reorder (&y5, &y6);

      area.y = floor (MIN3 (y1, y2, y5)) - 1;
      area.height = ceil (MAX3 (y3, y4, y6)) + 3 - area.y;
    }
  else
    {
      area.y = floor (MIN (y1, y2)) - 1;
      area.height = ceil (MAX (y3, y4)) + 3 - area.y;
    }

  return area;
}
Esempio n. 2
0
static void
lens_distort_func (gfloat              *src_buf,
                   gfloat              *dst_buf,
                   const GeglRectangle *extended,
                   const GeglRectangle *result,
                   const GeglRectangle *boundary,
                   LensValues          *lens,
                   gint                 xx,
                   gint                 yy,
                   GeglBuffer          *input,
                   gfloat              *background)
{
  gdouble sx, sy, mag;
  gdouble brighten;
  gfloat  pixel_buffer [16 * 4], temp[4];
  gdouble dx, dy;
  gint    x_int, y_int, x = 0, y = 0, offset = 0;

  temp[0] = temp[1] = temp[2] = temp[3] = 0.0;

  lens_get_source_coord ((gdouble) xx, (gdouble) yy, &sx, &sy, &mag, lens);

  /* pseudo gamma transformation, since the input is scRGB */
  brighten = pow (MAX (1.0 + mag * lens->brighten, 0.0), 2.4);

  x_int = floor (sx);
  dx = sx - x_int;

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

  for (y = y_int - 1; y <= y_int + 2; y++)
    {
      for (x = x_int - 1; x <= x_int + 2; x++)
        {
          gint b;

          if (x < boundary->x || x >= (boundary->x + boundary->width) ||
              y < boundary->y || y >= (boundary->y + boundary->height))
            {
              for (b = 0; b < 4; b++)
                pixel_buffer[offset++] = background[b];
            }
          else
            {

              if (x >= extended->x && x < (extended->x + extended->width) &&
                  y >= extended->y && y < (extended->y + extended->height))
                {
                  gint src_off;
                  src_off = (y - extended->y) * extended->width * 4 +
                    (x - extended->x) * 4;

                  for (b = 0; b < 4; b++)
                    temp[b] = src_buf[src_off++];
                }
              else
                {
                  gegl_buffer_sample (input, x, y, NULL, temp,
                                      babl_format ("RGBA float"),
                                      GEGL_SAMPLER_LINEAR,
                                      GEGL_ABYSS_CLAMP);
                }

              for (b = 0; b < 4; b++)
                pixel_buffer[offset++] = temp[b];
            }
        }
    }

  lens_cubic_interpolate (pixel_buffer, temp, dx, dy, brighten);

  offset = (yy - result->y) * result->width * 4 + (xx - result->x) * 4;

  for (x = 0; x < 4; x++)
    dst_buf[offset++] = temp[x];
}
Esempio n. 3
0
static void
lens_distort_func (gfloat              *src_buf,
                   gfloat              *dst_buf,
                   const GeglRectangle *extended,
                   const GeglRectangle *result,
                   const GeglRectangle *boundary,
                   LensDistortion       old,
                   gint                 xx,
                   gint                 yy,
                   GeglBuffer          *input)
{
  gdouble sx, sy, mag;
  gdouble brighten;
  gfloat  pixel_buffer [16 * 4], temp[4];
  gdouble dx, dy;
  gint    x_int, y_int, x = 0, y = 0, offset = 0;

  temp[0] = temp[1] = temp[2] = temp[3] = 0.0;

  lens_get_source_coord ((gdouble)xx, (gdouble)yy, &sx, &sy, &mag, &old);

  brighten = 1.0 + mag * old.brighten;

  x_int = floor (sx);
  dx = sx - x_int;

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

  for (y = y_int - 1; y <= y_int + 2; y++)
    {
      for (x = x_int - 1; x <= x_int + 2; x++)
        {
          gint b;

          if (x >= extended->x && x<(extended->x + extended->width)
              && y >= extended->y && y < (extended->y + extended->height))
            {
              gint src_off;
              src_off = (y - extended->y) * extended->width * 4 +
                (x - extended->x) * 4;
              for (b=0; b<4; b++)
                temp[b] = src_buf[src_off++];

            }
          else if (x >= boundary->x && x < boundary->x + boundary->width &&
                   y >= boundary->y && y < boundary->y + boundary->height)
            {
              gegl_buffer_sample (input, x, y, NULL, temp,
                                  babl_format ("RGBA float"),
                                  GEGL_SAMPLER_CUBIC,
                                  GEGL_ABYSS_NONE);
            }
          else
            {
              for (b=0; b<4; b++)
                temp[b] = 0.0;
            }

          for (b=0; b<4; b++)
            pixel_buffer[offset++] = temp[b];
        }
    }

  lens_cubic_interpolate (pixel_buffer, temp, dx, dy, brighten);

  offset = (yy - result->y) * result->width * 4 + (xx - result->x) * 4;
  for (x=0; x<4; x++)
    dst_buf[offset++] = temp[x];
}