Example #1
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
    GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
    GeglBuffer   *temp_in;
    GeglRectangle compute  = gegl_operation_get_required_for_output (operation, "input", result);

    if (result->width == 0 ||
            result->height== 0 ||
            o->radius < 1.0)
    {
        output = g_object_ref (input);
    }
    else
    {
        temp_in = gegl_buffer_create_sub_buffer (input, &compute);
        snn_percentile (temp_in, output, o->radius, o->percentile, o->pairs);
        g_object_unref (temp_in);
    }

    return  TRUE;
}
Example #2
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle compute;

  if (o->blur_radius >= 1.0 && gegl_cl_is_accelerated ())
    if (cl_process (operation, input, output, result))
      return TRUE;

  compute = gegl_operation_get_required_for_output (operation, "input",result);

  if (o->blur_radius < 1.0)
    {
      gegl_buffer_copy (input, result, output, result);
    }
  else
    {
      bilateral_filter (input, &compute, output, result, o->blur_radius, o->edge_preservation);
    }

  return  TRUE;
}
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO          *o = GEGL_CHANT_PROPERTIES (operation);
  GeglBuffer          *temp_in;
  GeglRectangle        compute;

  if (gegl_cl_is_accelerated ())
    if (cl_process (operation, input, output, result))
      return TRUE;

  compute  = gegl_operation_get_required_for_output (
                   operation, "input", result);

  if (o->radius < 1.0)
    {
      output = g_object_ref (input);
    }
  else
    {
      temp_in = gegl_buffer_create_sub_buffer (input, &compute);

      snn_mean (temp_in, output, result, o->radius, o->pairs);
      g_object_unref (temp_in);
    }

  return  TRUE;
}
Example #4
0
static GeglRectangle
get_required_for_output (GeglOperation        *operation,
                         const gchar         *input_pad,
                         const GeglRectangle *roi)
{
  if (operation->node->is_graph)
    {
      return gegl_operation_get_required_for_output (operation, input_pad, roi);
    }

  return *roi;
}
Example #5
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle compute = gegl_operation_get_required_for_output (operation, "input", result);

  demosaic (o, input, &compute, output, result);

  return  TRUE;
}
Example #6
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  GeglRectangle src_rect = gegl_operation_get_required_for_output (operation, "input", result);

  demosaic (o, input, &src_rect, output, result);

  return  TRUE;
}
Example #7
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle input_rect = gegl_operation_get_required_for_output (operation, "input", result);

  hor_min ( input, &input_rect, output, result, o->radius);
  ver_min (output,      result, output, result, o->radius);

  return  TRUE;
}
Example #8
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  gint    i, j;
  gfloat *buf1, *buf2, *buf3;

  if (gegl_operation_use_opencl (operation))
    if (cl_process (operation, input, output, result))
      return TRUE;

  buf1 = g_new (gfloat, SQR (CHUNK_SIZE + LAPLACE_RADIUS * 2) * 4);
  buf2 = g_new (gfloat, SQR (CHUNK_SIZE + LAPLACE_RADIUS * 2) * 4);
  buf3 = g_new (gfloat, SQR (CHUNK_SIZE) * 4);

  for (j = 0; (j-1) * CHUNK_SIZE < result->height; j++)
    for (i = 0; (i-1) * CHUNK_SIZE < result->width; i++)
      {
        GeglRectangle chunked_result;
        GeglRectangle compute;

        chunked_result = *GEGL_RECTANGLE (result->x + i * CHUNK_SIZE,
                                          result->y + j * CHUNK_SIZE,
                                          CHUNK_SIZE, CHUNK_SIZE);

        gegl_rectangle_intersect (&chunked_result, &chunked_result, result);

        if (chunked_result.width < 1  || chunked_result.height < 1)
          continue;

        compute = gegl_operation_get_required_for_output (operation,
                                                          "input",
                                                          &chunked_result);

        edge_laplace (input, &compute, output, &chunked_result,
                      buf1, buf2, buf3);
      }

  g_free (buf1);
  g_free (buf2);
  g_free (buf3);

  return  TRUE;
}
Example #9
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglBuffer   *temp_in;
  GeglRectangle compute = gegl_operation_get_required_for_output (operation, "input", result);

  temp_in = gegl_buffer_create_sub_buffer (input, &compute);

  kuwahara (temp_in, output, o->radius);
  g_object_unref (temp_in);

  return  TRUE;
}
Example #10
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle compute;
  compute = gegl_operation_get_required_for_output (operation, "input",result);

  c2g (input, &compute, output, result,
       o->radius,
       o->samples,
       o->iterations,
       /*o->rgamma*/RGAMMA);

  return  TRUE;
}
Example #11
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglRectangle compute;

  if (gegl_cl_is_accelerated ())
    if (cl_process (operation, input, output, result))
      return TRUE;

  compute = gegl_operation_get_required_for_output (operation, "input", result);
  edge_laplace (input, &compute, output, result);

  return  TRUE;
}
Example #12
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  GeglRectangle input_rect = gegl_operation_get_required_for_output (operation, "input", result);

  if (gegl_cl_is_accelerated ())
    if (cl_process (operation, input, output, result))
      return TRUE;

  hor_min ( input, &input_rect, output, result, o->radius);
  ver_min (output,      result, output, result, o->radius);

  return  TRUE;
}
Example #13
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle compute;
  gboolean has_alpha;

  compute = gegl_operation_get_required_for_output (operation, "input", result);
  has_alpha = babl_format_has_alpha (gegl_operation_get_format (operation, "output"));

  if (gegl_operation_use_opencl (operation))
    if (cl_process (operation, input, output, result, has_alpha))
      return TRUE;

  edge_sobel (input, &compute, output, result, o->horizontal, o->vertical, o->keep_signal, has_alpha);
  return TRUE;
}
void
gegl_graph_prepare_request (GeglGraphTraversal  *path,
                            const GeglRectangle *request_roi,
                            gint                 level)
{
  GList *list_iter = NULL;
  static const GeglRectangle empty_rect = {0, 0, 0, 0};

  g_return_if_fail (path->bfs_path);

  if (path->rects_dirty)
    {
      /* Zero all the needs rects so we can intersect with them below */
      for (list_iter = path->bfs_path; list_iter; list_iter = list_iter->next)
        {
          GeglNode *node = GEGL_NODE (list_iter->data);
          GeglOperationContext *context = g_hash_table_lookup (path->contexts, node);

          /* We only need to reset the need rect, result will always get overwritten */
          gegl_operation_context_set_need_rect (context, &empty_rect);

          /* Reset cached status, because the rect we need may have changed */
          context->cached = FALSE;
        }
    }

  path->rects_dirty = TRUE;

  {
    /* Prep the first node */
    GeglNode *node = GEGL_NODE (path->bfs_path->data);
    GeglOperationContext *context = g_hash_table_lookup (path->contexts, node);
    GeglRectangle new_need;

    g_return_if_fail (context);

    gegl_rectangle_intersect (&new_need, &node->have_rect, request_roi);

    gegl_operation_context_set_need_rect (context, &new_need);
    gegl_operation_context_set_result_rect (context, &new_need);
  }
  
  /* Iterate over all the nodes and propagate the requested rectangle */
  for (list_iter = path->bfs_path; list_iter; list_iter = list_iter->next)
    {
      GeglNode             *node      = GEGL_NODE (list_iter->data);
      GeglOperation        *operation = node->operation;
      GeglOperationContext *context;
      GeglRectangle        *request;
      GSList               *input_pads;
      
      context = g_hash_table_lookup (path->contexts, node);
      g_return_if_fail (context);
      
      request = gegl_operation_context_get_need_rect (context);

      if (request->width == 0 || request->height == 0)
        {
          gegl_operation_context_set_result_rect (context, &empty_rect);
          continue;
        }
      
      if (node->cache)
        {
          gint i;
          for (i = level; i >=0 && !context->cached; i--)
          {
            if (gegl_region_rect_in (node->cache->valid_region[level], request) == GEGL_OVERLAP_RECTANGLE_IN)
            {
              /* This node is cached and the cache fulfills our need rect */
              context->cached = TRUE;
              gegl_operation_context_set_result_rect (context, &empty_rect);
            }
          }
          if (context->cached)
            continue;
        }

      {
        /* Expand request if the operation has a minimum processing requirement */
        GeglRectangle full_request = gegl_operation_get_cached_region (operation, request);

        gegl_operation_context_set_need_rect (context, &full_request);

        /* FIXME: We could trim this down based on the cache, instead of being all or nothing */
        gegl_operation_context_set_result_rect (context, request);

        for (input_pads = node->input_pads; input_pads; input_pads = input_pads->next)
          {
            GeglPad *source_pad = gegl_pad_get_connected_to (input_pads->data);

            if (source_pad)
              {
                GeglNode             *source_node    = gegl_pad_get_node (source_pad);
                GeglOperationContext *source_context = g_hash_table_lookup (path->contexts, source_node);
                const gchar          *pad_name       = gegl_pad_get_name (input_pads->data);

                GeglRectangle rect, current_need, new_need;

                /* Combine this need rect with any existing request */
                rect = gegl_operation_get_required_for_output (operation, pad_name, &full_request);
                current_need = *gegl_operation_context_get_need_rect (source_context);

                gegl_rectangle_bounding_box (&new_need, &rect, &current_need);

                /* Limit request to the nodes output */
                gegl_rectangle_intersect (&new_need, &source_node->have_rect, &new_need);

                gegl_operation_context_set_need_rect (source_context, &new_need);
              }
          }
      }
    }
}
Example #15
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);

  gdouble         percentile           = o->percentile       / 100.0;
  gdouble         alpha_percentile     = o->alpha_percentile / 100.0;
  const gint     *neighborhood_outline = o->user_data;

  const Babl     *format               = gegl_operation_get_format (operation, "input");
  gint            n_components         = babl_format_get_n_components (format);
  gboolean        has_alpha            = babl_format_has_alpha (format);

  G_STATIC_ASSERT (sizeof (gint32) == sizeof (gfloat));
  gint32         *src_buf;
  gfloat         *dst_buf;
  GeglRectangle   src_rect;
  gint            src_stride;
  gint            dst_stride;
  gint            n_pixels;

  Histogram      *hist;

  const gint32   *src;
  gfloat         *dst;
  gint            dst_x, dst_y;
  Direction       dir;

  gint            i;
  gint            c;

  src_rect   = gegl_operation_get_required_for_output (operation, "input", roi);
  src_stride = src_rect.width * n_components;
  dst_stride = roi->width * n_components;
  n_pixels   = roi->width * roi->height;
  dst_buf = g_new0 (gfloat, n_pixels                         * n_components);
  src_buf = g_new0 (gint32, src_rect.width * src_rect.height * n_components);

  gegl_buffer_get (input, &src_rect, 1.0, format, src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
  convert_values_to_bins (src_buf, n_components, has_alpha,
                          src_rect.width * src_rect.height);

  hist = g_slice_new0 (Histogram);

  src = src_buf + o->radius * (src_rect.width + 1) * n_components;
  dst = dst_buf;

  /* compute the first window */

  for (i = -o->radius; i <= o->radius; i++)
    {
      histogram_modify_vals (hist, src, n_components, src_stride, has_alpha,
                             i, -neighborhood_outline[abs (i)],
                             i, +neighborhood_outline[abs (i)],
                             +1);

      hist->size += 2 * neighborhood_outline[abs (i)] + 1;
    }

  for (c = 0; c < 3; c++)
    dst[c] = histogram_get_median (hist, c, percentile);

  if (has_alpha)
    dst[3] = histogram_get_median (hist, 3, alpha_percentile);

  dst_x = 0;
  dst_y = 0;

  n_pixels--;
  dir = LEFT_TO_RIGHT;

  while (n_pixels--)
    {
      /* move the src coords based on current direction and positions */
      if (dir == LEFT_TO_RIGHT)
        {
          if (dst_x != roi->width - 1)
            {
              dst_x++;
              src += n_components;
              dst += n_components;
            }
          else
            {
              dst_y++;
              src += src_stride;
              dst += dst_stride;
              dir = TOP_TO_BOTTOM;
            }
        }
      else if (dir == TOP_TO_BOTTOM)
        {
          if (dst_x == 0)
            {
              dst_x++;
              src += n_components;
              dst += n_components;
              dir = LEFT_TO_RIGHT;
            }
          else
            {
              dst_x--;
              src -= n_components;
              dst -= n_components;
              dir = RIGHT_TO_LEFT;
            }
        }
      else if (dir == RIGHT_TO_LEFT)
        {
          if (dst_x != 0)
            {
              dst_x--;
              src -= n_components;
              dst -= n_components;
            }
          else
            {
              dst_y++;
              src += src_stride;
              dst += dst_stride;
              dir = TOP_TO_BOTTOM;
            }
        }

      histogram_update (hist, src, n_components, src_stride, has_alpha,
                        o->neighborhood, o->radius, neighborhood_outline,
                        dir);

      for (c = 0; c < 3; c++)
        dst[c] = histogram_get_median (hist, c, percentile);

      if (has_alpha)
        dst[3] = histogram_get_median (hist, 3, alpha_percentile);
    }

  gegl_buffer_set (output, roi, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

  g_slice_free (Histogram, hist);
  g_free (dst_buf);
  g_free (src_buf);

  return TRUE;
}
Example #16
0
static gboolean
gegl_affine_process (GeglOperation        *operation,
                     GeglOperationContext *context,
                     const gchar          *output_prop,
                     const GeglRectangle  *result)
{
  GeglBuffer          *input;
  GeglBuffer          *output;
  GeglMatrix3          matrix;
  OpAffine            *affine = (OpAffine *) operation;

  gegl_affine_create_composite_matrix (affine, &matrix);

  if (gegl_affine_is_intermediate_node (affine) ||
      gegl_matrix3_is_identity (&matrix))
    {
      /* passing straight through (like gegl:nop) */
      input  = gegl_operation_context_get_source (context, "input");
      if (!input)
        {
          g_warning ("transform received NULL input");
          return FALSE;
        }

      gegl_operation_context_take_object (context, "output", G_OBJECT (input));
    }
  else if (gegl_affine_matrix3_allow_fast_translate (&matrix) ||
           (gegl_matrix3_is_translate (&matrix) &&
            ! strcmp (affine->filter, "nearest")))
    {
      /* doing a buffer shifting trick, (enhanced nop) */
      input  = gegl_operation_context_get_source (context, "input");

      output = g_object_new (GEGL_TYPE_BUFFER,
                             "source",    input,
                             "shift-x",   (int)-matrix.coeff[0][2],
                             "shift-y",   (int)-matrix.coeff[1][2],
                             "abyss-width", -1,  /* turn of abyss
                                                    (relying on abyss
                                                    of source) */
                         NULL);

      if (gegl_object_get_has_forked (input))
        gegl_object_set_has_forked (output);

      gegl_operation_context_take_object (context, "output", G_OBJECT (output));

      if (input != NULL)
        g_object_unref (input);
    }
  else if (gegl_affine_matrix3_allow_fast_reflect_x (&matrix))
    {
      GeglRectangle      src_rect;
      GeglSampler       *sampler;
      GeglRectangle      context_rect;

      input  = gegl_operation_context_get_source (context, "input");
      if (!input)
        {
          g_warning ("transform received NULL input");
          return FALSE;
        }

      output = gegl_operation_context_get_target (context, "output");

      src_rect = gegl_operation_get_required_for_output (operation, "output", result);
      src_rect.y += 1;

      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
          gegl_sampler_type_from_string (affine->filter));
      context_rect = *gegl_sampler_get_context_rect (sampler);

      src_rect.width -= context_rect.width;
      src_rect.height -= context_rect.height;

      gegl_affine_fast_reflect_x (output, input, result, &src_rect);
      g_object_unref (sampler);

      if (input != NULL)
        g_object_unref (input);
    }
  else if (gegl_affine_matrix3_allow_fast_reflect_y (&matrix))
    {
      GeglRectangle      src_rect;
      GeglSampler       *sampler;
      GeglRectangle      context_rect;

      input  = gegl_operation_context_get_source (context, "input");
      if (!input)
        {
          g_warning ("transform received NULL input");
          return FALSE;
        }

      output = gegl_operation_context_get_target (context, "output");

      src_rect = gegl_operation_get_required_for_output (operation, "output", result);
      src_rect.x += 1;

      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
          gegl_sampler_type_from_string (affine->filter));
      context_rect = *gegl_sampler_get_context_rect (sampler);

      src_rect.width -= context_rect.width;
      src_rect.height -= context_rect.height;

      gegl_affine_fast_reflect_y (output, input, result, &src_rect);
      g_object_unref (sampler);

      if (input != NULL)
        g_object_unref (input);
    }
  else
    {
      /* for all other cases, do a proper resampling */
      GeglSampler *sampler;

      input  = gegl_operation_context_get_source (context, "input");
      output = gegl_operation_context_get_target (context, "output");

      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
          gegl_sampler_type_from_string (affine->filter));
      affine_generic (output, input, &matrix, sampler);
      g_object_unref (sampler);

      if (input != NULL)
        g_object_unref (input);
    }

  return TRUE;
}
Example #17
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
    GeglProperties *o  = GEGL_PROPERTIES (operation);
    const Babl *format = gegl_operation_get_format (operation, "input");
    gint n_components  = babl_format_get_n_components (format);
    gboolean has_alpha = babl_format_has_alpha (format);

    gfloat *src_buf;
    gfloat *dst_buf;
    gint    n_pixels;
    GeglRectangle src_rect;

    Histogram *hist;
    Direction  dir;

    gint src_x, src_y;
    gint dst_x, dst_y;
    gint dst_idx, src_idx;
    gint xmin, ymin, xmax, ymax;

    src_rect = gegl_operation_get_required_for_output (operation, "input", roi);
    n_pixels = roi->width * roi->height;
    dst_buf = g_new0 (gfloat, n_pixels * n_components);
    src_buf = g_new0 (gfloat, src_rect.width * src_rect.height * n_components);

    gegl_buffer_get (input, &src_rect, 1.0, format, src_buf,
                     GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

    hist = g_slice_new0 (Histogram);

    dst_x = 0;
    dst_y = 0;
    src_x = o->radius;
    src_y = o->radius;

    /* compute the first window */

    hist->xmin = src_x - o->radius;
    hist->ymin = src_y - o->radius;
    hist->xmax = src_x + o->radius;
    hist->ymax = src_y + o->radius;

    histogram_add_vals (hist, src_buf, &src_rect, n_components,
                        hist->xmin, hist->ymin,
                        hist->xmax, hist->ymax);

    dst_idx = (dst_x + dst_y * roi->width) * n_components;

    dst_buf[dst_idx]     = histogram_get_median (hist, 0);
    dst_buf[dst_idx + 1] = histogram_get_median (hist, 1);
    dst_buf[dst_idx + 2] = histogram_get_median (hist, 2);

    if (has_alpha)
    {
        src_idx = (src_x + src_y * src_rect.width) * n_components;
        dst_buf[dst_idx + 3] = src_buf[src_idx + 3];
    }

    n_pixels--;
    dir = LEFT_TO_RIGHT;

    while (n_pixels--)
    {
        /* move the src coords based on current direction and positions */
        if (dir == LEFT_TO_RIGHT)
        {
            if (dst_x != roi->width - 1)
            {
                src_x++;
                dst_x++;
            }
            else
            {
                src_y++;
                dst_y++;
                dir = TOP_TO_BOTTOM;
            }
        }
        else if (dir == TOP_TO_BOTTOM)
        {
            if (dst_x == 0)
            {
                src_x++;
                dst_x++;
                dir = LEFT_TO_RIGHT;
            }
            else
            {
                src_x--;
                dst_x--;
                dir = RIGHT_TO_LEFT;
            }
        }
        else if (dir == RIGHT_TO_LEFT)
        {
            if (dst_x != 0)
            {
                src_x--;
                dst_x--;
            }
            else
            {
                src_y++;
                dst_y++;
                dir = TOP_TO_BOTTOM;
            }
        }

        xmin = src_x - o->radius;
        ymin = src_y - o->radius;
        xmax = src_x + o->radius;
        ymax = src_y + o->radius;

        histogram_update (hist, src_buf, &src_rect, n_components,
                          xmin, ymin, xmax, ymax, dir);

        dst_idx = (dst_x + dst_y * roi->width) * n_components;

        dst_buf[dst_idx]     = histogram_get_median (hist, 0);
        dst_buf[dst_idx + 1] = histogram_get_median (hist, 1);
        dst_buf[dst_idx + 2] = histogram_get_median (hist, 2);

        if (has_alpha)
        {
            src_idx = (src_x + src_y * src_rect.width) * n_components;
            dst_buf[dst_idx + 3] = src_buf[src_idx + 3];
        }
    }

    gegl_buffer_set (output, roi, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

    g_free (src_buf);
    g_free (dst_buf);
    g_slice_free (Histogram, hist);

    return TRUE;
}
Example #18
0
File: edge.c Project: jonnor/gegl
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o      = GEGL_PROPERTIES (operation);
  const Babl     *format = gegl_operation_get_format (operation, "output");
  gint            components = babl_format_get_n_components (format);
  gboolean        has_alpha  = babl_format_has_alpha (format);

  gfloat *src_buff;
  gfloat *dst_buff;
  GeglRectangle rect;
  gint x, y, ix, iy, b, idx;

  rect = gegl_operation_get_required_for_output (operation, "input", roi);

  src_buff = g_new (gfloat, rect.width * rect.height * components);
  dst_buff = g_new0 (gfloat, roi->width * roi->height * components);

  gegl_buffer_get (input, &rect, 1.0, format, src_buff,
                   GEGL_AUTO_ROWSTRIDE, o->border_behavior);

  for (y = 0; y < roi->height; y++)
    {
      iy = y + 1;
      for (x = 0; x < roi->width; x++)
        {
          ix = x + 1;
          for (b = 0; b < 3; b++)
            {

#define SRCPIX(X,Y,B) src_buff[((X) + (Y) * rect.width) * components + B]

              gfloat window[9];
              window[0] = SRCPIX(ix - 1, iy - 1, b);
              window[1] = SRCPIX(ix, iy - 1, b);
              window[2] = SRCPIX(ix + 1, iy - 1, b);
              window[3] = SRCPIX(ix - 1, iy, b);
              window[4] = SRCPIX(ix, iy, b);
              window[5] = SRCPIX(ix + 1, iy, b);
              window[6] = SRCPIX(ix - 1, iy + 1, b);
              window[7] = SRCPIX(ix, iy + 1, b);
              window[8] = SRCPIX(ix + 1, iy + 1, b);

              idx = (x + y * roi->width) * components + b;

              switch (o->algorithm)
                {
                  default:
                  case GEGL_EDGE_SOBEL:
                    dst_buff[idx] = edge_sobel (window, o->amount);
                    break;

                  case GEGL_EDGE_PREWITT:
                    dst_buff[idx] = edge_prewitt (window, o->amount);
                    break;

                  case GEGL_EDGE_GRADIENT:
                    dst_buff[idx] = edge_gradient (window, o->amount);
                    break;

                  case GEGL_EDGE_ROBERTS:
                    dst_buff[idx] = edge_roberts (window, o->amount);
                    break;

                  case GEGL_EDGE_DIFFERENTIAL:
                    dst_buff[idx] = edge_differential (window, o->amount);
                    break;

                  case GEGL_EDGE_LAPLACE:
                    dst_buff[idx] = edge_laplace (window, o->amount);
                    break;
                }
            }

          if (has_alpha)
            dst_buff[idx + 1] = SRCPIX(ix, iy, 3);
        }
#undef SRCPIX
    }

  gegl_buffer_set (output, roi, level, format, dst_buff, GEGL_AUTO_ROWSTRIDE);

  g_free (src_buff);
  g_free (dst_buff);

  return TRUE;
}
Example #19
0
GeglBuffer *
gegl_operation_context_dup_input_maybe_copy (GeglOperationContext *context,
                                             const gchar          *padname,
                                             const GeglRectangle  *roi)
{
  GeglBuffer    *input;
  GeglBuffer    *output;
  GeglBuffer    *result;
  GeglRectangle  required;
  GeglRectangle  temp;
  gint           shift_x;
  gint           shift_y;
  gint           tile_width;
  gint           tile_height;

  input = GEGL_BUFFER (gegl_operation_context_get_object (context, padname));

  if (! input)
    return NULL;

  /* return input directly when processing a level greater than 0, since
   * gegl_buffer_copy() only copies level-0 tiles
   */
  if (context->level > 0)
    return g_object_ref (input);

  output = GEGL_BUFFER (gegl_operation_context_get_object (context, "output"));

  /* return input directly when processing in-place, otherwise, the copied
   * input buffer will occupy space in the cache after the original is modified
   */
  if (input == output)
    return g_object_ref (input);

  /* get required region to copy */
  required = gegl_operation_get_required_for_output (context->operation,
                                                     padname, roi);

  /* return input directly if the required rectangle is infinite, so that we
   * don't attempt to copy an infinite region
   */
  if (gegl_rectangle_is_infinite_plane (&required))
    return g_object_ref (input);

  /* align required region to the tile grid */
  shift_x     = input->shift_x;
  shift_y     = input->shift_y;
  tile_width  = input->tile_width;
  tile_height = input->tile_height;

  temp.x      = (gint) floor ((gdouble) (required.x                   + shift_x) / tile_width)  * tile_width;
  temp.y      = (gint) floor ((gdouble) (required.y                   + shift_y) / tile_height) * tile_height;
  temp.width  = (gint) ceil  ((gdouble) (required.x + required.width  + shift_x) / tile_width)  * tile_width  - temp.x;
  temp.height = (gint) ceil  ((gdouble) (required.y + required.height + shift_y) / tile_height) * tile_height - temp.y;

  temp.x -= shift_x;
  temp.y -= shift_y;

  required = temp;

  /* intersect required region with input abyss */
  gegl_rectangle_intersect (&required, &required, &input->abyss);

  /* create new buffer with similar characteristics to the input buffer */
  result = g_object_new (GEGL_TYPE_BUFFER,
                         "format",       input->soft_format,
                         "x",            input->extent.x,
                         "y",            input->extent.y,
                         "width",        input->extent.width,
                         "height",       input->extent.height,
                         "abyss-x",      input->abyss.x,
                         "abyss-y",      input->abyss.y,
                         "abyss-width",  input->abyss.width,
                         "abyss-height", input->abyss.height,
                         "shift-x",      shift_x,
                         "shift-y",      shift_y,
                         "tile-width",   tile_width,
                         "tile-height",  tile_height,
                         NULL);

  /* if the tile size doesn't match, bail */
  if (result->tile_width != tile_width || result->tile_height != tile_height)
    {
      g_object_unref (result);

      return g_object_ref (input);
    }

  /* copy required region from input to result -- tiles will generally be COWed */
  gegl_buffer_copy (input,  &required, GEGL_ABYSS_NONE,
                    result, &required);

  return result;
}