示例#1
0
static void
prepare (GeglOperation *operation)
{
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglProperties              *o       = GEGL_PROPERTIES (operation);
  GeglRectangle           *whole_region;
  gdouble                  angle   = o->angle * G_PI / 180.0;

  while (angle < 0.0)
    angle += 2 * G_PI;

  whole_region = gegl_operation_source_get_bounding_box (operation, "input");

  if (whole_region != NULL)
    {
      gdouble center_x = gegl_coordinate_relative_to_pixel (o->center_x, 
                                                            whole_region->width);
      gdouble center_y = gegl_coordinate_relative_to_pixel (o->center_y,
                                                            whole_region->height);
      gdouble maxr_x = MAX (fabs (center_x - whole_region->x),
                            fabs (center_x - whole_region->x - whole_region->width));
      gdouble maxr_y = MAX (fabs (center_y - whole_region->y),
                            fabs (center_y - whole_region->y - whole_region->height));

      if (angle >= G_PI)
        angle = G_PI;

      op_area->left = op_area->right
        = ceil (maxr_y * sin (angle / 2.0)) + 1;

      op_area->top = op_area->bottom
        = ceil (maxr_x * sin (angle / 2.0)) + 1;
    }
  else
    {
      op_area->left   =
      op_area->right  =
      op_area->top    =
      op_area->bottom = 0;
    }

  gegl_operation_set_format (operation, "input",  babl_format ("RaGaBaA float"));
  gegl_operation_set_format (operation, "output", babl_format ("RaGaBaA float"));
}
示例#2
0
static void
prepare (GeglOperation *operation)
{
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglProperties          *o       = GEGL_PROPERTIES (operation);
  GeglRectangle           *whole_region;

  whole_region = gegl_operation_source_get_bounding_box (operation, "input");

  if (whole_region != NULL)
    {
     gdouble center_x, center_y;

     center_x = gegl_coordinate_relative_to_pixel (
                  o->center_x, whole_region->width);
     center_y = gegl_coordinate_relative_to_pixel (
                  o->center_y, whole_region->height);

      op_area->left = op_area->right
        = MAX (fabs (whole_region->x - center_x),
               fabs (whole_region->width + whole_region->x - center_x)) * fabs (o->factor) +1;

      op_area->top = op_area->bottom
        = MAX (fabs (whole_region->y - center_y),
               fabs (whole_region->height + whole_region->y - center_y)) * fabs (o->factor) +1;
    }
  else
    {
      op_area->left   =
      op_area->right  =
      op_area->top    =
      op_area->bottom = 0;
    }

  gegl_operation_set_format (operation, "input",  babl_format ("RaGaBaA float"));
  gegl_operation_set_format (operation, "output", babl_format ("RaGaBaA float"));
}
示例#3
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglProperties          *o       = GEGL_PROPERTIES (operation);
  gfloat                  *in_buf, *out_buf, *out_pixel;
  gint                     x, y;
  GeglRectangle            src_rect;

  GeglRectangle           *whole_region;
  gdouble                  center_x, center_y;

  whole_region = gegl_operation_source_get_bounding_box (operation, "input");
  center_x = gegl_coordinate_relative_to_pixel (
                o->center_x, whole_region->width);
  center_y = gegl_coordinate_relative_to_pixel (
                o->center_y, whole_region->height);

  src_rect = *roi;
  src_rect.x -= op_area->left;
  src_rect.y -= op_area->top;
  src_rect.width += op_area->left + op_area->right;
  src_rect.height += op_area->top + op_area->bottom;

  in_buf  = g_new  (gfloat, src_rect.width * src_rect.height * 4);
  out_buf = g_new0 (gfloat, roi->width * roi->height * 4);
  out_pixel = out_buf;

  gegl_buffer_get (input, &src_rect, 1.0, babl_format ("RaGaBaA float"),
                   in_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  for (y = roi->y; y < roi->height + roi->y; ++y)
    {
      for (x = roi->x; x < roi->width + roi->x; ++x)
        {
          gint c, i;
          gfloat dxx, dyy, ix, iy, inv_xy_len;
          gfloat sum[] = {0, 0, 0, 0};

          gfloat x_start = x;
          gfloat y_start = y;
          gfloat x_end   = x + (center_x - (gfloat) x) * o->factor;
          gfloat y_end   = y + (center_y - (gfloat) y) * o->factor;

          gint dist = ceil (sqrt (SQR (x_end - x_start) + SQR (y_end - y_start)) +1);

          /* ensure quality when near the center or with small factor */
          gint xy_len = MAX (dist, 3);

          /* performance concern */
          if (xy_len > NOMINAL_NUM_IT)
            xy_len = MIN (NOMINAL_NUM_IT + (gint) sqrt (xy_len - NOMINAL_NUM_IT), MAX_NUM_IT);

          inv_xy_len = 1.0 / (gfloat) xy_len;

          dxx = (x_end - x_start) * inv_xy_len;
          dyy = (y_end - y_start) * inv_xy_len;

          ix  = x_start;
          iy  = y_start;

          for (i = 0; i < xy_len; i++)
            {
              gfloat dx = ix - floor (ix);
              gfloat dy = iy - floor (iy);

              /* do bilinear interpolation to get a nice smooth result */
              gfloat *pix0, *pix1, *pix2, *pix3;
              gfloat mixy0[4];
              gfloat mixy1[4];

              pix0 = get_pixel_color (in_buf, &src_rect, ix, iy);
              pix1 = get_pixel_color (in_buf, &src_rect, ix+1, iy);
              pix2 = get_pixel_color (in_buf, &src_rect, ix, iy+1);
              pix3 = get_pixel_color (in_buf, &src_rect, ix+1, iy+1);

              for (c = 0; c < 4; ++c)
                {
                  mixy0[c] = dy * (pix2[c] - pix0[c]) + pix0[c];
                  mixy1[c] = dy * (pix3[c] - pix1[c]) + pix1[c];

                  sum[c] +=  dx * (mixy1[c] - mixy0[c]) + mixy0[c];
                }

              ix += dxx;
              iy += dyy;
            }

          for (c = 0; c < 4; ++c)
            *out_pixel++ = sum[c] * inv_xy_len;
        }
    }

  gegl_buffer_set (output, roi, 0, babl_format ("RaGaBaA float"),
                   out_buf, GEGL_AUTO_ROWSTRIDE);

  g_free (in_buf);
  g_free (out_buf);

  return  TRUE;
}
示例#4
0
文件: waves.c 项目: jonnor/gegl
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties     *o       = GEGL_PROPERTIES (operation);
  GeglSampler        *sampler = gegl_buffer_sampler_new_at_level (input,
                                                         babl_format ("RGBA float"),
                                                         o->sampler_type,
                                                         level);
  GeglRectangle      *in_extent = gegl_operation_source_get_bounding_box (operation, "input");
  GeglBufferIterator *iter;

  GeglAbyssPolicy abyss = o->clamp ? GEGL_ABYSS_CLAMP : GEGL_ABYSS_NONE;

  gdouble px_x = gegl_coordinate_relative_to_pixel (o->x, in_extent->width);
  gdouble px_y = gegl_coordinate_relative_to_pixel (o->y, in_extent->height);

  gdouble scalex;
  gdouble scaley;

  if (o->aspect > 1.0)
    {
      scalex = 1.0;
      scaley = o->aspect;
    }
  else if (o->aspect < 1.0)
    {
      scalex = 1.0 / o->aspect;
      scaley = 1.0;
    }
  else
    {
      scalex = 1.0;
      scaley = 1.0;
    }

  iter = gegl_buffer_iterator_new (output, result, 0, babl_format ("RGBA float"),
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gint x = result->x;
      gint y = result->y;
      gfloat *out_pixel = iter->data[0];

      for (y = iter->roi[0].y; y < iter->roi[0].y + iter->roi[0].height; ++y)
        for (x = iter->roi[0].x; x < iter->roi[0].x + iter->roi[0].width; ++x)
          {
            gdouble radius;
            gdouble shift;
            gdouble dx;
            gdouble dy;
            gdouble ux;
            gdouble uy;

            dx = (x - px_x) * scalex;
            dy = (y - px_y) * scaley;

            if (!dx && !dy)
              radius = 0.000001;
            else
              radius = sqrt (dx * dx + dy * dy);

            shift = o->amplitude * sin (2.0 * G_PI * radius / o->period +
                                        2.0 * G_PI * o->phi);

            ux = dx / radius;
            uy = dy / radius;

            gegl_sampler_get (sampler,
                              x + (shift + ux) / scalex,
                              y + (shift + uy) / scaley,
                              NULL,
                              out_pixel,
                              abyss);

            out_pixel += 4;
          }
    }

  g_object_unref (sampler);

  return TRUE;
}
示例#5
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglProperties          *o       = GEGL_PROPERTIES (operation);
  gfloat                  *in_buf, *out_buf, *out_pixel;
  gint                     x, y;
  GeglRectangle            src_rect;
  GeglRectangle           *whole_region;
  gdouble                  angle;
  gdouble                  center_x, center_y;

  whole_region = gegl_operation_source_get_bounding_box (operation, "input");

  center_x = gegl_coordinate_relative_to_pixel (
                    o->center_x, whole_region->width);
  center_y = gegl_coordinate_relative_to_pixel (
                    o->center_y, whole_region->height);


  src_rect = *roi;
  src_rect.x -= op_area->left;
  src_rect.y -= op_area->top;
  src_rect.width += op_area->left + op_area->right;
  src_rect.height += op_area->top + op_area->bottom;

  in_buf    = g_new  (gfloat, src_rect.width * src_rect.height * 4);
  out_buf   = g_new0 (gfloat, roi->width * roi->height * 4);
  out_pixel = out_buf;

  gegl_buffer_get (input, &src_rect, 1.0, babl_format ("RaGaBaA float"),
                   in_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  angle = o->angle * G_PI / 180.0;

  while (angle < 0.0)
    angle += 2 * G_PI;

  for (y = roi->y; y < roi->height + roi->y; ++y)
    {
      for (x = roi->x; x < roi->width + roi->x; ++x)
        {
          gint c, i;
          gdouble phi_base, phi_start, phi_step;
          gfloat sum[] = {0, 0, 0, 0};
          gint count = 0;

          gdouble xr = x - center_x;
          gdouble yr = y - center_y;
          gdouble radius  = sqrt (SQR (xr) + SQR (yr));

          /* This is not the "real" length, a bit shorter */
          gdouble arc_length = radius * angle * SQRT_2;

          /* ensure quality with small angles */
          gint n = MAX (ceil (arc_length), 3);

          /* performance concern */
          if (n > NOMINAL_NUM_IT)
            n = NOMINAL_NUM_IT + (gint) sqrt (n - NOMINAL_NUM_IT);

          phi_base = compute_phi (xr, yr);
          phi_start = phi_base + angle / 2.0;
          phi_step = angle / (gdouble) n;

          /* Iterate other the arc */
          for (i = 0; i < n; i++)
            {
              gfloat s_val = sin (phi_start - i * phi_step);
              gfloat c_val = cos (phi_start - i * phi_step);

              gfloat ix = center_x + radius * c_val;
              gfloat iy = center_y + radius * s_val;

              if (ix >= whole_region->x && ix < whole_region->x + whole_region->width &&
                  iy >= whole_region->y && iy < whole_region->y + whole_region->height)
                {
                  /* do bilinear interpolation to get a nice smooth result */
                  gfloat dx = ix - floor (ix);
                  gfloat dy = iy - floor (iy);

                  gfloat *pix0, *pix1, *pix2, *pix3;
                  gfloat mixy0[4];
                  gfloat mixy1[4];

                  pix0 = get_pixel_color (in_buf, &src_rect, ix, iy);
                  pix1 = get_pixel_color (in_buf, &src_rect, ix+1, iy);
                  pix2 = get_pixel_color (in_buf, &src_rect, ix, iy+1);
                  pix3 = get_pixel_color (in_buf, &src_rect, ix+1, iy+1);

                  for (c = 0; c < 4; ++c)
                    {
                      mixy0[c] = dy * (pix2[c] - pix0[c]) + pix0[c];
                      mixy1[c] = dy * (pix3[c] - pix1[c]) + pix1[c];

                      sum[c] +=  dx * (mixy1[c] - mixy0[c]) + mixy0[c];
                    }

                  count++;
                }
            }

          if (count == 0)
            {
              gfloat *pix = get_pixel_color (in_buf, &src_rect, x, y);
              for (c = 0; c < 4; ++c)
                *out_pixel++ = pix[c];
            }
          else
            {
              for (c = 0; c < 4; ++c)
                *out_pixel++ = sum[c] / (gfloat) count;
            }
        }
    }

  gegl_buffer_set (output, roi, 0, babl_format ("RaGaBaA float"),
                   out_buf, GEGL_AUTO_ROWSTRIDE);

  g_free (in_buf);
  g_free (out_buf);

  return  TRUE;
}