Exemple #1
0
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint err;
  gint j;
  cl_int cl_err;

  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,   result, out_format, GEGL_CL_BUFFER_WRITE, GEGL_ABYSS_NONE);
  gint read = gegl_buffer_cl_iterator_add_2 (i, input, result, in_format,  GEGL_CL_BUFFER_READ, op_area->left, op_area->right, op_area->top, op_area->bottom, GEGL_ABYSS_NONE);
  gint aux  = gegl_buffer_cl_iterator_add_2 (i, NULL, result, in_format,  GEGL_CL_BUFFER_AUX, op_area->left, op_area->right, op_area->top, op_area->bottom, GEGL_ABYSS_NONE);
  while (gegl_buffer_cl_iterator_next (i, &err))
  {
    if (err) return FALSE;
    for (j=0; j < i->n; j++)
    {
      cl_err = cl_edge_laplace(i->tex[read][j], i->tex[aux][j], i->tex[0][j], &i->roi[read][j], &i->roi[0][j], LAPLACE_RADIUS);
      if (cl_err != CL_SUCCESS)
      {
        g_warning("[OpenCL] Error in gegl:edge-laplace: %s", gegl_cl_errstring(cl_err));
        return FALSE;
      }
    }
  }
  return TRUE;
}
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint err;
  gint j;
  cl_int cl_err;

  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,   result, out_format, GEGL_CL_BUFFER_WRITE, GEGL_ABYSS_NONE);
  gint read = gegl_buffer_cl_iterator_add (i, input, result, in_format,  GEGL_CL_BUFFER_READ, GEGL_ABYSS_NONE);
  while (gegl_buffer_cl_iterator_next (i, &err))
  {
    if (err) return FALSE;
    for (j=0; j < i->n; j++)
    {
      cl_err = cl_mono_mixer(i->tex[read][j], i->tex[0][j], i->size[0][j], &i->roi[0][j], o->red ,o->green , o->blue);

      if (cl_err != CL_SUCCESS)
      {
        g_warning("[OpenCL] Error in gegl:mono-mixer: %s", gegl_cl_errstring(cl_err));
        return FALSE;
      }
    }
  }
  return TRUE;
}
static gboolean
gegl_operation_point_filter_process (GeglOperation       *operation,
                                     GeglBuffer          *input,
                                     GeglBuffer          *output,
                                     const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  GeglOperationPointFilterClass *point_filter_class;

  point_filter_class = GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation);

  if ((result->width > 0) && (result->height > 0))
    {

      {
        GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, out_format, GEGL_BUFFER_WRITE);
        gint read = /*output == input ? 0 :*/ gegl_buffer_iterator_add (i, input,  result, in_format, GEGL_BUFFER_READ);
        /* using separate read and write iterators for in-place ideally a single
         * readwrite indice would be sufficient
         */
          while (gegl_buffer_iterator_next (i))
            point_filter_class->process (operation, i->data[read], i->data[0], i->length, &i->roi[0]);
      }
    }
  return TRUE;
}
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint err;
  gint j;
  cl_int cl_err;

  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,   result, out_format, GEGL_CL_BUFFER_WRITE, GEGL_ABYSS_NONE);
                gint read = gegl_buffer_cl_iterator_add_2 (i, input, result, in_format, GEGL_CL_BUFFER_READ, op_area->left, op_area->right, op_area->top, op_area->bottom, GEGL_ABYSS_NONE);
  while (gegl_buffer_cl_iterator_next (i, &err))
  {
    if (err) return FALSE;
    for (j=0; j < i->n; j++)
    {
      cl_err = cl_bilateral_filter(i->tex[read][j], i->tex[0][j], i->size[0][j], &i->roi[0][j], ceil(o->blur_radius), o->edge_preservation);
      if (cl_err != CL_SUCCESS)
      {
        g_warning("[OpenCL] Error in gegl:bilateral-filter: %s", gegl_cl_errstring(cl_err));
        return FALSE;
      }
    }
  }
  return TRUE;
}
Exemple #5
0
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");

  gint err;

  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,
                                                         result,
                                                         out_format,
                                                         GEGL_CL_BUFFER_WRITE);

  gint read = gegl_buffer_cl_iterator_add_2 (i,
                                             input,
                                             result,
                                             in_format,
                                             GEGL_CL_BUFFER_READ,
                                             op_area->left,
                                             op_area->right,
                                             op_area->top,
                                             op_area->bottom,
                                             GEGL_ABYSS_NONE);

  gint aux  = gegl_buffer_cl_iterator_add_2 (i,
                                             NULL,
                                             result,
                                             in_format,
                                             GEGL_CL_BUFFER_AUX,
                                             0,
                                             0,
                                             op_area->top,
                                             op_area->bottom,
                                             GEGL_ABYSS_NONE);

  while (gegl_buffer_cl_iterator_next (i, &err))
    {
      if (err) return FALSE;

      err = cl_box_max(i->tex[read],
                       i->tex[aux],
                       i->tex[0],
                       i->size[0],
                       &i->roi[0],
                       ceil (o->radius));

      if (err) return FALSE;
    }

  return TRUE;
}
Exemple #6
0
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");

  gint err = 0;

  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglProperties *o = GEGL_PROPERTIES (operation);

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,
                                                         result,
                                                         out_format,
                                                         GEGL_CL_BUFFER_WRITE);

  gint read = gegl_buffer_cl_iterator_add_2 (i,
                                             input,
                                             result,
                                             in_format,
                                             GEGL_CL_BUFFER_READ,
                                             op_area->left,
                                             op_area->right,
                                             op_area->top,
                                             op_area->bottom,
                                             GEGL_ABYSS_CLAMP);

  gint aux = gegl_buffer_cl_iterator_add_aux (i,
                                              result,
                                              in_format,
                                              0,
                                              0,
                                              op_area->top,
                                              op_area->bottom);

  while (gegl_buffer_cl_iterator_next (i, &err) && !err)
    {
      err = cl_box_blur (i->tex[read],
                         i->tex[aux],
                         i->tex[0],
                         i->size[0],
                         &i->roi[0],
                         o->radius);

      if (err)
        {
          gegl_buffer_cl_iterator_stop (i);
          break;
        }
    }

  return !err;
}
Exemple #7
0
static void
prepare_cl (GeglOperation *operation)
{
    GeglOperationAreaFilter* op_area = GEGL_OPERATION_AREA_FILTER (operation);
    GeglChantO* o = GEGL_CHANT_PROPERTIES (operation);

    gdouble theta = o->angle * G_PI / 180.0;
    gdouble offset_x = fabs(o->length * cos(theta));
    gdouble offset_y = fabs(o->length * sin(theta));

    op_area->left   =
        op_area->right  = (gint)ceil(0.5 * offset_x);
    op_area->top    =
        op_area->bottom = (gint)ceil(0.5 * offset_y);

    GeglNode * self;
    GeglPad *pad;
    Babl * format=babl_format ("RaGaBaA float");
    self=gegl_operation_get_source_node(operation,"input");
    while(self) {
        if(strcmp(gegl_node_get_operation(self),"gimp:tilemanager-source")==0) {
            format=gegl_operation_get_format(self->operation,"output");
            break;
        }
        self=gegl_operation_get_source_node(self->operation,"input");
    }
    gegl_operation_set_format (operation, "output", format);
}
Exemple #8
0
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o  = GEGL_PROPERTIES (operation);
  const Babl *format = gegl_operation_get_format (operation, "input");

  memcpy (out_buf, in_buf, n_pixels * babl_format_get_bytes_per_pixel (format));

  if (o->cache != (void *) operation->node->cache)
    {
      if (o->cache)
        {
          g_object_unref (o->cache);
          o->cache = NULL;
        }

      if (operation->node->cache)
        o->cache = g_object_ref (operation->node->cache);
    }

  return TRUE;
}
static gboolean
gimp_operation_tile_source_process (GeglOperation       *operation,
                                    GeglBuffer          *output,
                                    const GeglRectangle *result)
{
  GimpOperationTileSource *self = GIMP_OPERATION_TILE_SOURCE (operation);
  const Babl              *format;
  PixelRegion              srcPR;
  gpointer                 pr;

  if (! self->tile_manager)
    return FALSE;

  format = gegl_operation_get_format (operation, "output");

  pixel_region_init (&srcPR, self->tile_manager,
                     result->x,     result->y,
                     result->width, result->height,
                     FALSE);

  for (pr = pixel_regions_register (1, &srcPR);
       pr;
       pr = pixel_regions_process (pr))
    {
      GeglRectangle rect = { srcPR.x, srcPR.y, srcPR.w, srcPR.h };

      gegl_buffer_set (output, &rect, 1, format, srcPR.data, srcPR.rowstride);
    }

  return TRUE;
}
static gboolean
bilateral_cl_process (GeglOperation       *operation,
                      GeglBuffer          *input,
                      GeglBuffer          *output,
                      const GeglRectangle *result,
                      gint                 s_sigma,
                      gfloat               r_sigma)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint err = 0;

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,
                                                         result,
                                                         out_format,
                                                         GEGL_CL_BUFFER_WRITE);

  gint read = gegl_buffer_cl_iterator_add (i,
                                           input,
                                           result,
                                           in_format,
                                           GEGL_CL_BUFFER_READ,
                                           GEGL_ABYSS_NONE);

  while (gegl_buffer_cl_iterator_next (i, &err) && !err)
    {
       err = cl_bilateral (i->tex[read],
                           i->tex[0],
                           &i->roi[0],
                           &i->roi[read],
                           s_sigma,
                           r_sigma);

      if (err)
        {
          gegl_buffer_cl_iterator_stop (i);
          break;
        }
    }

  return !err;
}
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result,
            const GeglRectangle *src_rect)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint err;
  gint j;
  cl_int cl_err;

  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  gdouble theta = o->angle * G_PI / 180.0;
  gfloat  offset_x = (gfloat)(o->length * cos(theta));
  gfloat  offset_y = (gfloat)(o->length * sin(theta));
  gint num_steps = (gint)ceil(o->length) + 1;

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,   result, out_format, GEGL_CL_BUFFER_WRITE, GEGL_ABYSS_NONE);
                gint read = gegl_buffer_cl_iterator_add_2 (i, input, result, in_format,  GEGL_CL_BUFFER_READ,
                                                           op_area->left, op_area->right, op_area->top, op_area->bottom, GEGL_ABYSS_NONE);
  while (gegl_buffer_cl_iterator_next (i, &err))
  {
    if (err) return FALSE;
    for (j=0; j < i->n; j++)
    {
      cl_err = cl_motion_blur(i->tex[read][j], i->tex[0][j], i->size[0][j], &i->roi[0][j], &i->roi[read][j], num_steps, offset_x, offset_y);
      if (cl_err != CL_SUCCESS)
      {
        g_warning("[OpenCL] Error in gegl:motion-blur: %s", gegl_cl_errstring(cl_err));
        return FALSE;
      }
    }
  }
  return TRUE;
}
Exemple #12
0
static gboolean
gegl_gblur_1d_process (GeglOperation       *operation,
                       GeglBuffer          *input,
                       GeglBuffer          *output,
                       const GeglRectangle *result,
                       gint                 level)
{
  GeglProperties *o      = GEGL_PROPERTIES (operation);
  const Babl *format = gegl_operation_get_format (operation, "output");

  GeglGblur1dFilter filter;
  GeglAbyssPolicy   abyss_policy = to_gegl_policy (o->abyss_policy);

  filter = filter_disambiguation (o->filter, o->std_dev);

  if (filter == GEGL_GBLUR_1D_IIR)
    {
      gdouble b[4], m[3][3];

      iir_young_find_constants (o->std_dev, b, m);

      if (o->orientation == GEGL_ORIENTATION_HORIZONTAL)
        iir_young_hor_blur (input, result, output, b, m, abyss_policy, format);
      else
        iir_young_ver_blur (input, result, output, b, m, abyss_policy, format);
    }
  else
    {
      gfloat *cmatrix;
      gint    clen;

      clen = fir_gen_convolve_matrix (o->std_dev, &cmatrix);

      /* FIXME: implement others format cases */
      if (gegl_operation_use_opencl (operation) &&
          format == babl_format ("RaGaBaA float"))
        if (fir_cl_process(input, output, result, format,
                           cmatrix, clen, o->orientation, abyss_policy))
          return TRUE;

      if (o->orientation == GEGL_ORIENTATION_HORIZONTAL)
        fir_hor_blur (input, result, output, cmatrix, clen, abyss_policy, format);
      else
        fir_ver_blur (input, result, output, cmatrix, clen, abyss_policy, format);

      gegl_free (cmatrix);
    }

  return  TRUE;
}
Exemple #13
0
gboolean
gegl_can_do_inplace_processing (GeglOperation       *operation,
                                GeglBuffer          *input,
                                const GeglRectangle *result)
{
  if (!input)
    return FALSE;
  if (gegl_object_get_has_forked (G_OBJECT (input)))
    return FALSE;

  if (gegl_buffer_get_format (input) == gegl_operation_get_format (operation, "output") &&
      gegl_rectangle_contains (gegl_buffer_get_extent (input), result))
    return TRUE;
  return FALSE;
}
Exemple #14
0
static gboolean
checkerboard_cl_process (GeglOperation       *operation,
                         cl_mem               out_tex,
                         size_t               global_worksize,
                         const GeglRectangle *roi,
                         gint                 level)
{
  GeglProperties *o         = GEGL_PROPERTIES (operation);
  const Babl   *out_format  = gegl_operation_get_format (operation, "output");
  const size_t  gbl_size[2] = {roi->width, roi->height};
  const size_t  gbl_offs[2] = {roi->x, roi->y};
  cl_int        cl_err      = 0;
  float         color1[4];
  float         color2[4];

  if (!cl_data)
  {
    const char *kernel_name[] = {"kernel_checkerboard", NULL};
    cl_data = gegl_cl_compile_and_build (checkerboard_cl_source, kernel_name);

    if (!cl_data)
      return TRUE;
  }

  gegl_color_get_pixel (o->color1, out_format, color1);
  gegl_color_get_pixel (o->color2, out_format, color2);

  cl_err = gegl_cl_set_kernel_args (cl_data->kernel[0],
                                    sizeof(cl_mem), &out_tex,
                                    sizeof(color1), &color1,
                                    sizeof(color2), &color2,
                                    sizeof(cl_int), &o->x,
                                    sizeof(cl_int), &o->y,
                                    sizeof(cl_int), &o->x_offset,
                                    sizeof(cl_int), &o->y_offset,
                                    NULL);
  CL_CHECK;

  cl_err = gegl_clEnqueueNDRangeKernel (gegl_cl_get_command_queue (),
                                        cl_data->kernel[0], 2,
                                        gbl_offs, gbl_size, NULL,
                                        0, NULL, NULL);
  CL_CHECK;

  return FALSE;
error:
  return TRUE;
}
Exemple #15
0
static gboolean
operation_source_process (GeglOperation       *operation,
                          GeglBuffer          *output,
                          const GeglRectangle *result,
                          gint                 level)
{
  const Babl *out_format = gegl_operation_get_format (operation, "output");

  if ((result->width > 0) && (result->height > 0))
    {
      GeglBufferIterator *iter;
      if (gegl_operation_use_opencl (operation) &&
          babl_format_get_n_components (out_format) == 4 &&
          babl_format_get_type (out_format, 0) == babl_type ("float"))
        {
          GeglBufferClIterator *cl_iter;
          gboolean err;

          GEGL_NOTE (GEGL_DEBUG_OPENCL, "GEGL_OPERATION_POINT_RENDER: %s", GEGL_OPERATION_GET_CLASS (operation)->name);

          cl_iter = gegl_buffer_cl_iterator_new (output, result, out_format, GEGL_CL_BUFFER_WRITE);

          while (gegl_buffer_cl_iterator_next (cl_iter, &err) && !err)
            {
              err = checkerboard_cl_process (operation, cl_iter->tex[0], cl_iter->size[0], &cl_iter->roi[0], level);

              if (err)
                {
                  gegl_buffer_cl_iterator_stop (cl_iter);
                  break;
                }
            }

          if (err)
            GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", GEGL_OPERATION_GET_CLASS (operation)->name);
          else
            return TRUE;
        }

      iter = gegl_buffer_iterator_new (output, result, level, out_format,
                                       GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (iter))
        checkerboard_process (operation, iter->data[0], iter->length, &iter->roi[0], level);
    }
  return TRUE;
}
Exemple #16
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *out_buf,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglBufferIterator *iter;
  const Babl         *out_format = gegl_operation_get_format (operation,
                                                              "output");

  if (gegl_operation_use_opencl (operation))
    {
      GeglBufferClIterator *cl_iter;
      gboolean              err;

      GEGL_NOTE (GEGL_DEBUG_OPENCL, "GEGL_OPERATION_POINT_RENDER: %s",
                 GEGL_OPERATION_GET_CLASS (operation)->name);

      cl_iter = gegl_buffer_cl_iterator_new (out_buf, roi, out_format,
                                             GEGL_CL_BUFFER_WRITE);

      while (gegl_buffer_cl_iterator_next (cl_iter, &err) && !err)
        {
          err = cl_process (operation, cl_iter->tex[0], cl_iter->roi);

          if (err)
            {
              gegl_buffer_cl_iterator_stop (cl_iter);
              break;
            }
        }

      if (err)
        GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s",
                   GEGL_OPERATION_GET_CLASS (operation)->name);
      else
        return TRUE;
    }

  iter = gegl_buffer_iterator_new (out_buf, roi, level, out_format,
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    c_process (operation, iter->data[0], &iter->roi[0]);

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

  gint radius = ceil (o->radius);

  if (o->orientation == GEGL_ORIENTATION_HORIZONTAL)
    wav_hor_blur (input, output, result, radius, format);
  else
    wav_ver_blur (input, output, result, radius, format);

  return  TRUE;
}
Exemple #18
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;
}
Exemple #19
0
static gboolean
checkerboard_process (GeglOperation       *operation,
                      void                *out_buf,
                      glong                n_pixels,
                      const GeglRectangle *roi,
                      gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint        pixel_size = babl_format_get_bytes_per_pixel (out_format);
  guchar     *out_pixel = out_buf;
  void       *color1 = alloca(pixel_size);
  void       *color2 = alloca(pixel_size);
  gint        y;
  const gint  x_min = roi->x - o->x_offset;
  const gint  y_min = roi->y - o->y_offset;
  const gint  x_max = roi->x + roi->width - o->x_offset;
  const gint  y_max = roi->y + roi->height - o->y_offset;

  const gint  square_width  = o->x;
  const gint  square_height = o->y;

  if (level)
    return checkerboard_process_simple (operation, out_buf, n_pixels, roi, level);

  gegl_color_get_pixel (o->color1, out_format, color1);
  gegl_color_get_pixel (o->color2, out_format, color2);

  for (y = y_min; y < y_max; y++)
    {
      gint  x = x_min;
      void *cur_color;

      /* Figure out which box we're in */
      gint tilex = TILE_INDEX (x, square_width);
      gint tiley = TILE_INDEX (y, square_height);
      if ((tilex + tiley) % 2 == 0)
        cur_color = color1;
      else
        cur_color = color2;

      while (x < x_max)
        {
          /* Figure out how long this stripe is */
          gint count;
          gint stripe_end = (TILE_INDEX (x, square_width) + 1) * square_width;
               stripe_end = stripe_end > x_max ? x_max : stripe_end;

          count = stripe_end - x;

          gegl_memset_pattern (out_pixel, cur_color, pixel_size, count);
          out_pixel += count * pixel_size;
          x = stripe_end;

          if (cur_color == color1)
            cur_color = color2;
          else
            cur_color = color1;
        }
    }

  return TRUE;
}
Exemple #20
0
static gboolean
checkerboard_process_simple (GeglOperation       *operation,
                             void                *out_buf,
                             glong                n_pixels,
                             const GeglRectangle *roi,
                             gint                 level)
{
  gint        factor = 1 << level;
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *out_format = gegl_operation_get_format (operation, "output");

  gint        pixel_size = babl_format_get_bytes_per_pixel (out_format);
  guchar     *out_pixel = out_buf;
  void       *color1 = alloca(pixel_size);
  void       *color2 = alloca(pixel_size);

  gint        x = roi->x; /* initial x                   */
  gint        y = roi->y; /*           and y coordinates */

  gegl_color_get_pixel (o->color1, out_format, color1);
  gegl_color_get_pixel (o->color2, out_format, color2);

  while (n_pixels--)
    {
      gint nx,ny;

      if ((x - o->x_offset) < 0)
        {
          nx = div (x - o->x_offset + 1, o->x / factor).quot;
        }
      else
        {
          nx = div (x - o->x_offset, o->x / factor).quot;
        }

      if ((y - o->y_offset) < 0)
        {
          ny = div (y - o->y_offset + 1, o->y / factor).quot;
        }
      else
        {
          ny = div (y - o->y_offset, o->y / factor).quot;
        }

      /* shift negative cell indices */
      nx -= (x - o->x_offset) < 0 ? 1 : 0;
      ny -= (y - o->y_offset) < 0 ? 1 : 0;

      if ( (nx+ny) % 2 == 0)
        memcpy (out_pixel, color1, pixel_size);
      else
        memcpy (out_pixel, color2, pixel_size);

      out_pixel += pixel_size;

      /* update x and y coordinates */
      x++;
      if (x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
        }
    }

  return  TRUE;
}
Exemple #21
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, "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;
}
GeglBuffer *
gegl_operation_context_get_target (GeglOperationContext *context,
                                   const gchar          *padname)
{
  GeglBuffer          *output;
  const GeglRectangle *result;
  const Babl          *format;
  GeglNode            *node;
  GeglOperation       *operation;

#if 0
  g_return_val_if_fail (GEGL_IS_OPERATION_CONTEXT (context), NULL);
#endif

  operation = context->operation;
  node = operation->node; /* <ick */
  format = gegl_operation_get_format (operation, padname);

  if (format == NULL)
    {
      g_warning ("no format for %s presuming RGBA float\n",
                 gegl_node_get_debug_name (node));
      format = babl_format ("RGBA float");
    }
  g_assert (format != NULL);
  g_assert (!strcmp (padname, "output"));

  result = &context->result_rect;

  if (result->width == 0 ||
      result->height == 0)
    {
      output = g_object_ref (emptybuf());
    }
  else if (node->dont_cache == FALSE &&
      ! GEGL_OPERATION_CLASS (G_OBJECT_GET_CLASS (operation))->no_cache)
    {
      GeglBuffer    *cache;
      cache = GEGL_BUFFER (gegl_node_get_cache (node));

      /* Only use the cache if the result is within the cache
       * extent. This is certainly not optimal. My gut feeling is that
       * the current caching mechanism needs to be redesigned
       */
      if (gegl_rectangle_contains (gegl_buffer_get_extent (cache), result))
        {
          output = g_object_ref (cache);
        }
      else
        {
          output = gegl_buffer_new_ram (result, format);
        }
    }
  else
    {
      output = gegl_buffer_new_ram (result, format);
    }

  gegl_operation_context_take_object (context, padname, G_OBJECT (output));
  return output;
}
Exemple #23
0
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                samples,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *format = gegl_operation_get_format (operation, "input");
  gfloat     *in  = in_buf;
  gfloat     *out = out_buf;
  gint        component_index;
  gint        n_components;
  gdouble     min = 0.0;
  gdouble     max = 1.0;

  n_components = babl_format_get_n_components (format);

  switch (o->component)
    {
      case GEGL_COMPONENT_EXTRACT_RGB_RED:
      case GEGL_COMPONENT_EXTRACT_HUE:
      case GEGL_COMPONENT_EXTRACT_CMYK_CYAN:
      case GEGL_COMPONENT_EXTRACT_YCBCR_Y:
      case GEGL_COMPONENT_EXTRACT_LAB_L:
        {
          component_index = 0;

          if (o->component == GEGL_COMPONENT_EXTRACT_LAB_L)
            {
              max = 100.0;
            }
        }
      break;

      case GEGL_COMPONENT_EXTRACT_RGB_GREEN:
      case GEGL_COMPONENT_EXTRACT_HSV_SATURATION:
      case GEGL_COMPONENT_EXTRACT_HSL_SATURATION:
      case GEGL_COMPONENT_EXTRACT_CMYK_MAGENTA:
      case GEGL_COMPONENT_EXTRACT_YCBCR_CB:
      case GEGL_COMPONENT_EXTRACT_LAB_A:
      case GEGL_COMPONENT_EXTRACT_ALPHA:
        {
          component_index = 1;

          if (o->component == GEGL_COMPONENT_EXTRACT_YCBCR_CB)
            {
              min = -0.5;
              max =  0.5;
            }
          else if (o->component == GEGL_COMPONENT_EXTRACT_LAB_A)
            {
              min = -128.0;
              max =  127;
            }
        }
      break;
  
      case GEGL_COMPONENT_EXTRACT_RGB_BLUE:
      case GEGL_COMPONENT_EXTRACT_HSV_VALUE:
      case GEGL_COMPONENT_EXTRACT_HSL_LIGHTNESS:
      case GEGL_COMPONENT_EXTRACT_CMYK_YELLOW:
      case GEGL_COMPONENT_EXTRACT_YCBCR_CR:
      case GEGL_COMPONENT_EXTRACT_LAB_B:
        {
          component_index = 2;

          if (o->component == GEGL_COMPONENT_EXTRACT_YCBCR_CR)
            {
              min = -0.5;
              max =  0.5;
            }
          else if (o->component == GEGL_COMPONENT_EXTRACT_LAB_B)
            {
              min = -128.0;
              max =  127;
            }
        }
      break;
  
      case GEGL_COMPONENT_EXTRACT_CMYK_KEY:
        {
          component_index = 3;
        }
      break;
    }

    while (samples--)
      {
        gdouble value = in[component_index];
        
        if (min != 0.0 || max != 1.0)
          {
            gdouble scale  = 1.0 / (max - min);
            gdouble offset = -min; 
            value = CLAMP ((value + offset) * scale, 0.0, 1.0);
          }
        
        if (o->invert)
          out[0] = 1.0 - value;
        else
          out[0] = value;  

        in  += n_components;
        out += 1;
      }


  return TRUE;
}
Exemple #24
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
    gint          components;
    gint          col, c;
    gfloat       *rowbefore;
    gfloat       *rowthis;
    gfloat       *rowafter;
    gfloat       *dest;
    gfloat       *ninepix;
    gboolean      has_alpha;
    guint         alpha;
    const Babl   *format = gegl_operation_get_format (operation, "input");

    /* The rectangle of the current row we are working on */
    GeglRectangle rowrect;

    /* The rectangle of the sample we are going to take for the
     * next line (this does include the interpolation distance!) */
    GeglRectangle rownext_bufrect;

    components = babl_format_get_n_components (format);
    has_alpha  = babl_format_has_alpha (format);
    alpha      = components - 1;

    /* The original algorithm that appeared in GIMP did a manual clamping
     * of samples outside the input rectangle, by always allocating a
     * buffer which is 1-pixel wider than necessary, and then filling the
     * edges of the buffer with repetitions of the edges.
     * We don't need this complexity here thanks to the CLAMP abyss policy
     * which is implemented by GEGL. We still allocate buffers which are
     * larger, but we let GEGL fill the edges with the clamped values.
     */

    rowbefore  = g_new (gfloat, (roi->width + 2) * components);
    rowthis    = g_new (gfloat, (roi->width + 2) * components);
    rowafter   = g_new (gfloat, (roi->width + 2) * components);
    dest       = g_new (gfloat, roi->width * components);
    ninepix    = g_new (gfloat, 9 * components);

    gegl_rectangle_set (&rowrect, roi->x, roi->y, roi->width, 1);
    gegl_rectangle_set (&rownext_bufrect, roi->x - 1, roi->y - 1, roi->width + 2, 1);

    gegl_buffer_get (input, &rownext_bufrect, 1.0, format,
                     rowbefore, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
    ++rownext_bufrect.y;

    gegl_buffer_get (input, &rownext_bufrect, 1.0, format,
                     rowthis, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
    ++rownext_bufrect.y;

    gegl_buffer_get (input, &rownext_bufrect, 1.0, format,
                     rowafter, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
    ++rownext_bufrect.y;

    for (rowrect.y = roi->y; rowrect.y < (roi->y + roi->height); ++rowrect.y)
    {
        gfloat *tmp;

        /* this macro returns the current pixel if it has some opacity. Otherwise
         * it returns the center pixel of the current 3x3 area. */
#define USE_IF_ALPHA(p) (((!has_alpha) || *((p)+alpha)) ? (p) : &rowthis[(col+1) * components])

        for (col = 0; col < roi->width; ++col)
        {
            /* do 9x extrapolation pass */
            if (((!has_alpha) || (rowthis[(col + 1) * components + alpha] > 0)) &&
                    extrapolate9 (components,
                                  &ninepix[0 * components],
                                  &ninepix[1 * components],
                                  &ninepix[2 * components],
                                  &ninepix[3 * components],
                                  &ninepix[4 * components],
                                  &ninepix[5 * components],
                                  &ninepix[6 * components],
                                  &ninepix[7 * components],
                                  &ninepix[8 * components],
                                  USE_IF_ALPHA (&rowbefore[(col + 0) * components]),
                                  USE_IF_ALPHA (&rowbefore[(col + 1) * components]),
                                  USE_IF_ALPHA (&rowbefore[(col + 2) * components]),
                                  USE_IF_ALPHA (&rowthis  [(col + 0) * components]),
                                  &rowthis  [(col + 1) * components],
                                  USE_IF_ALPHA (&rowthis  [(col + 2) * components]),
                                  USE_IF_ALPHA (&rowafter [(col + 0) * components]),
                                  USE_IF_ALPHA (&rowafter [(col + 1) * components]),
                                  USE_IF_ALPHA (&rowafter [(col + 2) * components])
                                 ))
            {
                /* subsample results and put into dest */
                for (c = 0; c < components; ++c)
                {
#define NINEPIX(index, c) ninepix[(index) * components + (c)]
                    dest[(col * components) + c] =
                        (3 * NINEPIX(0, c) + 5 * NINEPIX(1, c) + 3 * NINEPIX(2, c) +
                         5 * NINEPIX(3, c) + 6 * NINEPIX(4, c) + 5 * NINEPIX(5, c) +
                         3 * NINEPIX(6, c) + 5 * NINEPIX(7, c) + 3 * NINEPIX(8, c)
                         /* The GIMP implementation added 19 (out of 255) here before
                          * normalizing (dividing by 38), which is equivalent to a
                          * call to "ceil". We don't need this since we are working
                          * with floating point numbers... */
                        ) / 38;
#undef NINEPIX
                }
            }
            else
            {
                memcpy (&dest[col * components], &rowthis[(col + 1) * components], components * sizeof(gfloat));
            }
        }

#undef USE_IF_ALPHA

        /* write result row to dest */
        gegl_buffer_set (output, &rowrect, 0, format, &dest[0], GEGL_AUTO_ROWSTRIDE);

        /* rotate pointers */
        tmp       = rowbefore;
        rowbefore = rowthis;
        rowthis   = rowafter;
        rowafter  = tmp;

        /* populate new after-row */
        gegl_buffer_get (input, &rownext_bufrect, 1.0, format,
                         rowafter, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
        ++rownext_bufrect.y;
    }

    g_free (rowbefore);
    g_free (rowthis);
    g_free (rowafter);
    g_free (dest);
    g_free (ninepix);

    return  TRUE;
}
Exemple #25
0
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *result)
{
  const Babl *in_format  = gegl_operation_get_format (operation, "input");
  const Babl *out_format = gegl_operation_get_format (operation, "output");

  gfloat    min[] = {1.0f, 1.0f, 1.0f, 1.0f};
  gfloat    max[] = {0.0f, 0.0f, 0.0f, 0.0f};
  gfloat    i_min[4], i_max[4], diff[4];
  cl_int    err = 0;
  gint      read, c;
  GeglBufferClIterator *i;
  GeglProperties           *o;
  cl_float4 cl_min, cl_diff;

  o = GEGL_PROPERTIES (operation);

  if (cl_build_kernels ())
    return FALSE;

  i = gegl_buffer_cl_iterator_new (input,
                                   result,
                                   in_format,
                                   GEGL_CL_BUFFER_READ);

  while (gegl_buffer_cl_iterator_next (i, &err) && !err)
    {
      err = cl_buffer_get_min_max (i->tex[0],
                                   i->size[0],
                                   &i->roi[0],
                                   i_min,
                                   i_max);
      if (err)
        {
          gegl_buffer_cl_iterator_stop (i);
          break;
        }

      for (c = 0; c < 3; c++)
        {
          if (i_min[c] < min[c])
            min[c] = i_min[c];
          if (i_max[c] > max[c])
            max[c] = i_max[c];
        }
    }

  if (err)
    return FALSE;

  if (o->keep_colors)
    reduce_min_max_global (min, max);

  for (c = 0; c < 3; c ++)
    {
      diff[c] = max[c] - min[c];

      /* Avoid a divide by zero error if the image is a solid color */
      if (diff[c] < 1e-3)
        {
          min[c]  = 0.0;
          diff[c] = 1.0;
        }
    }

  cl_diff.x = diff[0];
  cl_diff.y = diff[1];
  cl_diff.z = diff[2];
  cl_diff.w = 1.0;

  cl_min.x = min[0];
  cl_min.y = min[1];
  cl_min.z = min[2];
  cl_min.w = 0.0;

  i = gegl_buffer_cl_iterator_new (output,
                                   result,
                                   out_format,
                                   GEGL_CL_BUFFER_WRITE);

  read = gegl_buffer_cl_iterator_add_2 (i,
                                        input,
                                        result,
                                        in_format,
                                        GEGL_CL_BUFFER_READ,
                                        0,
                                        0,
                                        0,
                                        0,
                                        GEGL_ABYSS_NONE);

  while (gegl_buffer_cl_iterator_next (i, &err) && !err)
    {
      err = cl_stretch_contrast (i->tex[read],
                                 i->tex[0],
                                 i->size[0],
                                 &i->roi[0],
                                 cl_min,
                                 cl_diff);

      if (err)
        {
          gegl_buffer_cl_iterator_stop (i);
          break;
        }
    }

  return !err;
}
Exemple #26
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;
}
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties *o        = GEGL_PROPERTIES (operation);
  const Babl *src_format   = gegl_operation_get_source_format (operation, "input");
  const Babl *dst_format   = gegl_operation_get_format (operation, "output");
  gint        src_components = babl_format_get_n_components (src_format);
  gint        dst_components = babl_format_get_n_components (dst_format);

  gint     width, height;
  gint     row_size;
  gint     y;
  gdouble *top_row  = NULL;
  gdouble *dst_row  = NULL;
  gdouble *src_row  = NULL;
  gdouble *p_top    = NULL;
  gdouble *p_dst    = NULL;

  width = gegl_buffer_get_width (input);
  height = gegl_buffer_get_height (input);
  row_size = width + 1;

  top_row = g_new0 (gdouble, row_size * dst_components);
  dst_row = g_new0 (gdouble, row_size * dst_components);
  src_row = g_new  (gdouble, row_size * src_components);

  p_top = top_row;
  p_dst = dst_row;

  for (y = 0; y < height; y++)
    {
      GeglRectangle row_rect = {-1, y, width + 1, 1};

      gegl_buffer_get (input, &row_rect, 1.0, src_format, src_row,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      compute_row_integral (src_row + src_components,
                            p_top + dst_components,
                            p_dst + dst_components,
                            width,
                            src_components,
                            o->squared);

      gegl_buffer_set (output, &row_rect, 0, dst_format, p_dst,
                       GEGL_AUTO_ROWSTRIDE);

      p_top = p_dst;

      if (p_dst == top_row)
        p_dst = dst_row;
      else
        p_dst = top_row;
    }

  g_free (top_row);
  g_free (dst_row);
  g_free (src_row);

  return TRUE;
}
Exemple #28
0
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o         = GEGL_PROPERTIES (operation);
  const Babl     *format    = gegl_operation_get_format (operation, "input");
  gboolean        has_alpha = babl_format_has_alpha (format);
  gint            n_components = has_alpha ? 4 : 3;
  gfloat *input  = in_buf;
  gfloat *output = out_buf;

  if (o->clip_low && o->clip_high)
    {
      while (n_pixels--)
        {
          output[0] = CLAMP (input[0], o->low_limit, o->high_limit);
          output[1] = CLAMP (input[1], o->low_limit, o->high_limit);
          output[2] = CLAMP (input[2], o->low_limit, o->high_limit);

          if (has_alpha)
            output[3] = input[3];

          input  += n_components;
          output += n_components;
        }
    }

  else if (o->clip_high)
    {
      while (n_pixels--)
          {
            output[0] = input[0] > o->high_limit ? o->high_limit : input[0];
            output[1] = input[1] > o->high_limit ? o->high_limit : input[1];
            output[2] = input[2] > o->high_limit ? o->high_limit : input[2];

            if (has_alpha)
              output[3] = input[3];

            input  += n_components;
            output += n_components;
          }
    }

  else if (o->clip_low)
    {
      while (n_pixels--)
        {
          output[0] = input[0] < o->low_limit ? o->low_limit : input[0];
          output[1] = input[1] < o->low_limit ? o->low_limit : input[1];
          output[2] = input[2] < o->low_limit ? o->low_limit : input[2];

          if (has_alpha)
            output[3] = input[3];

          input  += n_components;
          output += n_components;
        }
    }

  return TRUE;
}
static gboolean
gegl_operation_point_composer3_process (GeglOperation       *operation,
                                        GeglBuffer          *input,
                                        GeglBuffer          *aux,
                                        GeglBuffer          *aux2,
                                        GeglBuffer          *output,
                                        const GeglRectangle *result,
                                        gint                 level)
{
  GeglOperationPointComposer3Class *point_composer3_class = GEGL_OPERATION_POINT_COMPOSER3_GET_CLASS (operation);
  const Babl *in_format   = gegl_operation_get_format (operation, "input");
  const Babl *aux_format  = gegl_operation_get_format (operation, "aux");
  const Babl *aux2_format = gegl_operation_get_format (operation, "aux2");
  const Babl *out_format  = gegl_operation_get_format (operation, "output");

  if ((result->width > 0) && (result->height > 0))
    {
      GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
      gint read  = gegl_buffer_iterator_add (i, input, result, level, in_format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

      if (aux)
        {
          gint foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
          if (aux2)
            {
              gint bar = gegl_buffer_iterator_add (i, aux2, result, level, aux2_format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

              while (gegl_buffer_iterator_next (i))
                {
                   point_composer3_class->process (operation, i->data[read], i->data[foo], i->data[bar], i->data[0], i->length, &(i->roi[0]), level);
                }
            }
          else
            {
              while (gegl_buffer_iterator_next (i))
                {
                   point_composer3_class->process (operation, i->data[read], i->data[foo], NULL, i->data[0], i->length, &(i->roi[0]), level);
                }
            }
        }
      else
        {
          if (aux2)
            {
              gint bar = gegl_buffer_iterator_add (i, aux2, result, level, aux2_format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
              while (gegl_buffer_iterator_next (i))
                {
                   point_composer3_class->process (operation, i->data[read], NULL, i->data[bar], i->data[0], i->length, &(i->roi[0]), level);
                }
            }
          else
            {
              while (gegl_buffer_iterator_next (i))
                {
                   point_composer3_class->process (operation, i->data[read], NULL, NULL, i->data[0], i->length, &(i->roi[0]), level);
                }
            }
        }
      return TRUE;
    }
  return TRUE;
}
Exemple #30
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;
}