Exemple #1
0
gboolean
gimp_gegl_mask_is_empty (GeglBuffer *buffer)
{
  GeglBufferIterator *iter;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE);

  iter = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("Y float"),
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *data = iter->data[0];
      gint    i;

      for (i = 0; i < iter->length; i++)
        {
          if (data[i])
            {
              gegl_buffer_iterator_stop (iter);

              return FALSE;
            }
        }
    }

  return TRUE;
}
static gboolean
gegl_operation_point_render_process (GeglOperation       *operation,
                                     GeglBuffer          *output,
                                     const GeglRectangle *result,
                                     gint                 level)
{
  GeglPad    *pad;
  const Babl *out_format;
  GeglOperationPointRenderClass *point_render_class;

  point_render_class = GEGL_OPERATION_POINT_RENDER_GET_CLASS (operation);

  pad        = gegl_node_get_pad (operation->node, "output");
  out_format = gegl_pad_get_format (pad);
  if (!out_format)
    {
      g_warning ("%s", gegl_node_get_debug_name (operation->node));
    }
  g_assert (out_format);

  if ((result->width > 0) && (result->height > 0))
    {
      GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (i))
          point_render_class->process (operation, i->data[0], i->length, &i->roi[0], level);
    }
  return TRUE;
}
static void
cdisplay_gamma_convert_buffer (GimpColorDisplay *display,
                               GeglBuffer       *buffer,
                               GeglRectangle    *area)
{
  CdisplayGamma      *gamma = CDISPLAY_GAMMA (display);
  GeglBufferIterator *iter;
  gdouble             one_over_gamma;

  one_over_gamma = 1.0 / gamma->gamma;

  iter = gegl_buffer_iterator_new (buffer, area, 0,
                                   babl_format ("R'G'B'A float"),
                                   GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *data  = iter->data[0];
      gint    count = iter->length;

      while (count--)
        {
          *data = pow (*data, one_over_gamma); data++;
          *data = pow (*data, one_over_gamma); data++;
          *data = pow (*data, one_over_gamma); data++;

          data++;
        }
    }
}
static void
tile_request_end(MyPaintTiledSurface *tiled_surface, MyPaintTileRequest *request)
{
    MyPaintGeglTiledSurface *self = (MyPaintGeglTiledSurface *)tiled_surface;

    if (buffer_is_native(self)) {
        GeglBufferIterator *iterator = (GeglBufferIterator *)request->context;

        if (iterator) {
            gegl_buffer_iterator_next(iterator);
            request->context = NULL;
        }
    } else {
        // Push our linear buffer back into the GeglBuffer
        const int tile_size = tiled_surface->tile_size;
        GeglRectangle tile_bbox;

        g_assert(request->buffer);
        gegl_rectangle_set(&tile_bbox, request->tx*tile_size, request->ty*tile_size, tile_size, tile_size);
        gegl_buffer_set(self->buffer, &tile_bbox, 0, self->format,
                        request->buffer, GEGL_AUTO_ROWSTRIDE);
        gegl_free(request->buffer);
    }

}
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;
}
Exemple #6
0
gboolean
gimp_gegl_mask_is_empty (GeglBuffer *buffer)
{
  GeglBufferIterator *iter;
  const Babl         *format;
  gint                bpp;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE);

  format = gegl_buffer_get_format (buffer);
  bpp    = babl_format_get_bytes_per_pixel (format);

  iter = gegl_buffer_iterator_new (buffer, NULL, 0, format,
                                   GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);

  while (gegl_buffer_iterator_next (iter))
    {
      if (! gegl_memeq_zero (iter->items[0].data, bpp * iter->length))
        {
          gegl_buffer_iterator_stop (iter);

          return FALSE;
        }
    }

  return TRUE;
}
Exemple #7
0
static void
cpn_affine_transform_clamp (GeglBuffer  *buffer,
                            gdouble      min,
                            gdouble      max)
{
  GeglBufferIterator *gi;

  gdouble scale = 1.0 / (max - min);
  gdouble offset = - min;

  /* We want to scale values linearly, regardless of the format of the buffer */
  gegl_buffer_set_format (buffer, babl_format ("Y double"));

  gi = gegl_buffer_iterator_new (buffer, NULL, 0, NULL,
                                 GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (gi))
    {
      guint k;
      double *data;

      data = (double*) gi->data[0];

      for (k = 0; k < gi->length; k++)
        {
          data[k] = CLAMP ((data[k] + offset) * scale, 0.0, 1.0);
        }
    }
}
Exemple #8
0
void
gimp_gegl_combine_mask (GeglBuffer          *mask_buffer,
                        const GeglRectangle *mask_rect,
                        GeglBuffer          *dest_buffer,
                        const GeglRectangle *dest_rect,
                        gdouble              opacity)
{
  GeglBufferIterator *iter;

  iter = gegl_buffer_iterator_new (mask_buffer, mask_rect, 0,
                                   babl_format ("Y float"),
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0,
                            babl_format ("Y float"),
                            GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      const gfloat *mask  = iter->data[0];
      gfloat       *dest  = iter->data[1];
      gint          count = iter->length;

      while (count--)
        {
          *dest *= *mask * opacity;

          mask += 1;
          dest += 1;
        }
    }
}
Exemple #9
0
static void
buffer_get_min_max (GeglBuffer *buffer,
                    gfloat     *min,
                    gfloat     *max)
{
  GeglBufferIterator *gi;
  gint c;
  gi = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("RGB float"),
                                 GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
  for (c = 0; c < 3; c++)
    {
      min[c] =  G_MAXFLOAT;
      max[c] = -G_MAXFLOAT;
    }

  while (gegl_buffer_iterator_next (gi))
    {
      gfloat *buf = gi->data[0];

      gint i;
      for (i = 0; i < gi->length; i++)
        {
          for (c = 0; c < 3; c++)
            {
              min[c] = MIN (buf [i * 3 + c], min[c]);
              max[c] = MAX (buf [i * 3 + c], max[c]);
            }
        }
    }
}
Exemple #10
0
static void
mean_rectangle_noalloc (GeglBuffer    *input,
                        GeglRectangle *rect,
                        GeglColor     *color)
{
  GeglBufferIterator *gi;
  gfloat              col[] = {0.0, 0.0, 0.0, 0.0};
  gint                c;

  gi = gegl_buffer_iterator_new (input, rect, 0, babl_format ("RaGaBaA float"),
                                 GEGL_ACCESS_READ, GEGL_ABYSS_CLAMP);

  while (gegl_buffer_iterator_next (gi))
    {
      gint    k;
      gfloat *data = (gfloat*) gi->data[0];

      for (k = 0; k < gi->length; k++)
        {
          for (c = 0; c < 4; c++)
            col[c] += data[c];

          data += 4;
        }
    }

  for (c = 0; c < 4; c++)
    col[c] /= rect->width * rect->height;

  gegl_color_set_pixel (color, babl_format ("RaGaBaA float"), col);
}
Exemple #11
0
/*
 * blend_pixels patched 8-24-05 to fix bug #163721.  Note that this change
 * causes the function to treat src1 and src2 asymmetrically.  This gives the
 * right behavior for the smudge tool, which is the only user of this function
 * at the time of patching.  If you want to use the function for something
 * else, caveat emptor.
 */
void
gimp_gegl_smudge_blend (GeglBuffer          *top_buffer,
                        const GeglRectangle *top_rect,
                        GeglBuffer          *bottom_buffer,
                        const GeglRectangle *bottom_rect,
                        GeglBuffer          *dest_buffer,
                        const GeglRectangle *dest_rect,
                        gdouble              blend)
{
  GeglBufferIterator *iter;

  iter = gegl_buffer_iterator_new (top_buffer, top_rect, 0,
                                   babl_format ("RGBA float"),
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, bottom_buffer, bottom_rect, 0,
                            babl_format ("RGBA float"),
                            GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0,
                            babl_format ("RGBA float"),
                            GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      const gfloat *top    = iter->data[0];
      const gfloat *bottom = iter->data[1];
      gfloat       *dest   = iter->data[2];
      gint          count  = iter->length;
      const gfloat  blend1 = 1.0 - blend;
      const gfloat  blend2 = blend;

      while (count--)
        {
          const gfloat a1 = blend1 * bottom[3];
          const gfloat a2 = blend2 * top[3];
          const gfloat a  = a1 + a2;
          gint         b;

          if (a == 0)
            {
              for (b = 0; b < 4; b++)
                dest[b] = 0;
            }
          else
            {
              for (b = 0; b < 3; b++)
                dest[b] =
                  bottom[b] + (bottom[b] * a1 + top[b] * a2 - a * bottom[b]);

              dest[3] = a;
            }

          top    += 4;
          bottom += 4;
          dest   += 4;
        }
    }
}
Exemple #12
0
static void
transfer_registration_color (GeglBuffer  *src,
                             GeglBuffer **dst,
                             gint         count)
{
  GimpRGB color, test;
  GeglBufferIterator *gi;
  const Babl *src_format, *dst_format;
  gint i, src_bpp, dst_bpp;
  gdouble white;

  gimp_context_get_foreground (&color);
  white = 1.0;

  src_format = gegl_buffer_get_format (src);
  src_bpp = babl_format_get_bytes_per_pixel (src_format);

  dst_format = gegl_buffer_get_format (dst[0]);
  dst_bpp = babl_format_get_bytes_per_pixel (dst_format);

  gi = gegl_buffer_iterator_new (src, NULL, 0, NULL,
                                 GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  for (i = 0; i < count; i++)
    {
      gegl_buffer_iterator_add (gi, dst[i], NULL, 0, NULL,
                                GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
    }

  while (gegl_buffer_iterator_next (gi))
    {
      guint j, k;
      gpointer src_data, dst_data[MAX_EXTRACT_IMAGES];

      src_data = gi->data[0];
      for (j = 0; j < count; j++)
        dst_data[j] = gi->data[j+1];

      for (k = 0; k < gi->length; k++)
        {
          gulong pos;
          pos = k * src_bpp;
          gimp_rgba_set_pixel (&test, src_format, ((guchar *)src_data) + pos);

          if (gimp_rgb_distance (&test, &color) < 1e-6)
            {
              for (j = 0; j < count; j++)
                {
                  gpointer data;
                  data = dst_data[j];
                  babl_process (babl_fish (babl_format ("Y double"), dst_format),
                                &white, (guchar *)data + (k * dst_bpp), 1);
                }
            }
        }
    }
}
Exemple #13
0
static void
process_standard (GeglBuffer          *input,
                  GeglBuffer          *output,
                  const GeglRectangle *result,
                  guint               *channel_bits,
                  GeglRandom          *rand,
                  GeglDitherStrategy   dither_strategy)
{
  GeglBufferIterator *gi;
  guint               channel_mask [4];

  generate_channel_masks (channel_bits, channel_mask);

  gi = gegl_buffer_iterator_new (input, result, 0, babl_format ("R'G'B'A u16"),
                                 GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (gi, output, result, 0, babl_format ("R'G'B'A u16"),
                            GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (gi))
    {
      guint    y;
      for (y = 0; y < gi->roi->height; y++)
        {
          switch (dither_strategy)
            {
            case GEGL_DITHER_NONE:
              process_row_no_dither (gi, channel_mask, channel_bits, y);
              break;
            case GEGL_DITHER_RANDOM:
              process_row_random (gi, channel_mask, channel_bits, y, rand);
              break;
            case GEGL_DITHER_RESILIENT:
              process_row_resilient (gi, channel_mask, channel_bits, y, rand);
              break;
            case GEGL_DITHER_RANDOM_COVARIANT:
              process_row_random_covariant (gi, channel_mask, channel_bits, y, rand);
              break;
            case GEGL_DITHER_BAYER:
              process_row_bayer (gi, channel_mask, channel_bits, y);
              break;
            case GEGL_DITHER_FLOYD_STEINBERG:
              /* Done separately */
              break;
            default:
              process_row_no_dither (gi, channel_mask, channel_bits, y);
            }
        }
    }
}
Exemple #14
0
TEST ()
{
  GeglBuffer    *buffer2, *buffer;
  GeglRectangle  bound = {0, 0, 20, 20};
  GeglRectangle  dest = {4, 4, 4, 6};
  float *blank = g_malloc0 (100000);
  gchar *temp = g_malloc0 (100000);
  test_start ();

  buffer2 = gegl_buffer_new (&bound, babl_format ("Y float"));
  buffer = gegl_buffer_new (&bound, babl_format ("Y float"));

  vgrad (buffer2);

  gegl_buffer_set (buffer2, &dest, 1, babl_format ("Y float"), blank, GEGL_AUTO_ROWSTRIDE);
  print_buffer (buffer2);

  gegl_buffer_get (buffer2, &bound, 0.5, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
  gegl_buffer_set (buffer, &bound, 0, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE);

  print_buffer (buffer);

  vgrad (buffer2);

  {
    GeglBufferIterator *iterator = gegl_buffer_iterator_new (buffer2,
        &dest, 1, babl_format ("Y float"), GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
    while (gegl_buffer_iterator_next (iterator))
    {
      int i;
      gfloat *d = iterator->data[0];
      for (i = 0; i < iterator->length; i++)
        d[i] = 0;
    }
  }
  print_buffer (buffer2);

  gegl_buffer_get (buffer2, &bound, 0.5, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
  gegl_buffer_set (buffer, &bound, 0, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE);

  print_buffer (buffer);

  g_object_unref (buffer);
  g_object_unref (buffer2);

  test_end ();

}
void
mask_components_onto (GeglBuffer        *src_buffer,
                      GeglBuffer        *aux_buffer,
                      GeglBuffer        *dst_buffer,
                      GeglRectangle     *roi,
                      GimpComponentMask  mask,
                      gboolean           linear_mode)
{
  GeglBufferIterator *iter;
  const Babl         *iterator_format;

  if (linear_mode)
    iterator_format = babl_format ("RGBA float");
  else
    iterator_format = babl_format ("R'G'B'A float");

  iter = gegl_buffer_iterator_new (dst_buffer, roi, 0,
                                   iterator_format,
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, src_buffer, roi, 0,
                            iterator_format,
                            GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, aux_buffer, roi, 0,
                            iterator_format,
                            GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *dest    = (gfloat *)iter->data[0];
      gfloat *src     = (gfloat *)iter->data[1];
      gfloat *aux     = (gfloat *)iter->data[2];
      glong   samples = iter->length;

      while (samples--)
        {
          dest[RED]   = (mask & GIMP_COMPONENT_MASK_RED)   ? aux[RED]   : src[RED];
          dest[GREEN] = (mask & GIMP_COMPONENT_MASK_GREEN) ? aux[GREEN] : src[GREEN];
          dest[BLUE]  = (mask & GIMP_COMPONENT_MASK_BLUE)  ? aux[BLUE]  : src[BLUE];
          dest[ALPHA] = (mask & GIMP_COMPONENT_MASK_ALPHA) ? aux[ALPHA] : src[ALPHA];

          src  += 4;
          aux  += 4;
          dest += 4;
        }
    }
}
static void
tile_request_start(MyPaintTiledSurface *tiled_surface, MyPaintTileRequest *request)
{
    MyPaintGeglTiledSurface *self = (MyPaintGeglTiledSurface *)tiled_surface;

    const int tile_size = tiled_surface->tile_size;
    GeglRectangle tile_bbox;
    gegl_rectangle_set(&tile_bbox, request->tx * tile_size, request->ty * tile_size, tile_size, tile_size);

    int read_write_flags;

    if (request->readonly) {
        read_write_flags = GEGL_BUFFER_READ;
    } else {
        read_write_flags = GEGL_BUFFER_READWRITE;

        // Extend the bounding box
        gegl_rectangle_bounding_box(&self->extent_rect, &self->extent_rect, &tile_bbox);
        gboolean success = gegl_buffer_set_extent(self->buffer, &self->extent_rect);
        g_assert(success);
    }

    if (buffer_is_native(self)) {
        GeglBufferIterator *iterator = gegl_buffer_iterator_new(self->buffer, &tile_bbox, 0, self->format,
                                      read_write_flags, GEGL_ABYSS_NONE);

        // Read out
        gboolean completed = gegl_buffer_iterator_next(iterator);
        g_assert(completed);

        if (iterator->length != tile_size*tile_size) {
            g_critical("Unable to get tile aligned access to GeglBuffer");
            request->buffer = NULL;
        } else {
            request->buffer = (uint16_t *)(iterator->data[0]);
        }

        // So we can finish the iterator in tile_request_end()
        request->context = (void *)iterator;
    } else {
        // Extract a linear rectangular chunk of appropriate BablFormat,
        // potentially triggering copying and color conversions
        request->buffer = alloc_for_format(self->format, tile_size*tile_size);
        gegl_buffer_get(self->buffer, &tile_bbox, 1, self->format,
                        request->buffer, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
        g_assert(request->buffer);
    }
}
Exemple #17
0
void
gimp_gegl_combine_mask_weird (GeglBuffer          *mask_buffer,
                              const GeglRectangle *mask_rect,
                              GeglBuffer          *dest_buffer,
                              const GeglRectangle *dest_rect,
                              gdouble              opacity,
                              gboolean             stipple)
{
  GeglBufferIterator *iter;

  iter = gegl_buffer_iterator_new (mask_buffer, mask_rect, 0,
                                   babl_format ("Y float"),
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0,
                            babl_format ("Y float"),
                            GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      const gfloat *mask  = iter->data[0];
      gfloat       *dest  = iter->data[1];
      gint          count = iter->length;

      if (stipple)
        {
          while (count--)
            {
              dest[0] += (1.0 - dest[0]) * *mask * opacity;

              mask += 1;
              dest += 1;
            }
        }
      else
        {
          while (count--)
            {
              if (opacity > dest[0])
                dest[0] += (opacity - dest[0]) * *mask * opacity;

              mask += 1;
              dest += 1;
            }
        }
    }
}
Exemple #18
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 #19
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 #20
0
static void fill_rect (GeglBuffer          *buffer,
                       const GeglRectangle *roi,
                       gfloat               value
                       )
{
  GeglBufferIterator *gi;
  gi = gegl_buffer_iterator_new (buffer, roi, 0, NULL,
                                 GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
  while (gegl_buffer_iterator_next (gi))
    {
      gfloat *buf = gi->data[0];
      gint    i;
      for (i=0; i<gi->length; i++)
        {
          buf[i]=value;
        }
    }
}
void
canvas_buffer_to_paint_buf_alpha (GimpTempBuf  *paint_buf,
                                  GeglBuffer   *canvas_buffer,
                                  gint          x_offset,
                                  gint          y_offset)
{
  /* Copy the canvas buffer in rect to the paint buffer's alpha channel */
  GeglRectangle roi;
  GeglBufferIterator *iter;

  const guint paint_stride = gimp_temp_buf_get_width (paint_buf);
  gfloat *paint_data       = (gfloat *) gimp_temp_buf_get_data (paint_buf);

  roi.x = x_offset;
  roi.y = y_offset;
  roi.width  = gimp_temp_buf_get_width (paint_buf);
  roi.height = gimp_temp_buf_get_height (paint_buf);

  iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0,
                                   babl_format ("Y float"),
                                   GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *canvas_pixel = (gfloat *)iter->data[0];
      int iy, ix;

      for (iy = 0; iy < iter->roi[0].height; iy++)
        {
          int paint_offset = (iy + iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x - roi.x;
          float *paint_pixel = &paint_data[paint_offset * 4];

          for (ix = 0; ix < iter->roi[0].width; ix++)
            {
              paint_pixel[3] *= *canvas_pixel;

              canvas_pixel += 1;
              paint_pixel  += 4;
            }
        }
    }
}
static void
buffer_get_auto_strech_data (GeglBuffer      *buffer,
                             AutostretchData *data)
{
  gfloat smin =  G_MAXFLOAT;
  gfloat smax = -G_MAXFLOAT;
  gfloat vmin =  G_MAXFLOAT;
  gfloat vmax = -G_MAXFLOAT;

  GeglBufferIterator *gi;

  gi = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("HSVA float"),
                                 GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (gi))
    {
      gfloat *buf = gi->data[0];
      gint    i;

      for (i = 0; i < gi->length; i++)
        {
          gfloat sval = buf[1];
          gfloat vval = buf[2];

          smin = MIN (sval, smin);
          smax = MAX (sval, smax);
          vmin = MIN (vval, vmin);
          vmax = MAX (vval, vmax);

          buf += 4;
        }
    }

  if (data)
    {
      data->slo   = smin;
      data->sdiff = smax - smin;
      data->vlo   = vmin;
      data->vdiff = vmax - vmin;
    }
}
Exemple #23
0
static void
cdisplay_proof_convert_buffer (GimpColorDisplay *display,
                               GeglBuffer       *buffer,
                               GeglRectangle    *area)
{
  CdisplayProof      *proof = CDISPLAY_PROOF (display);
  GeglBufferIterator *iter;

  if (! proof->transform)
    return;

  iter = gegl_buffer_iterator_new (buffer, area, 0,
                                   babl_format ("R'G'B'A float"),
                                   GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *data = iter->data[0];

      cmsDoTransform (proof->transform, data, data, iter->length);
    }
}
static void
cdisplay_lcms_convert_buffer (GimpColorDisplay *display,
                              GeglBuffer       *buffer,
                              GeglRectangle    *area)
{
  CdisplayLcms       *lcms = CDISPLAY_LCMS (display);
  GeglBufferIterator *iter;

  if (! lcms->transform)
    return;

  iter = gegl_buffer_iterator_new (buffer, area, 0,
                                   babl_format ("R'G'B'A float"),
                                   GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *data = iter->data[0];

      cmsDoTransform (lcms->transform, data, data, iter->length);
    }
}
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  AutostretchData     data;
  GeglBufferIterator *gi;

  buffer_get_auto_strech_data (input, &data);
  clean_autostretch_data (&data);

  gi = gegl_buffer_iterator_new (input, result, 0, babl_format ("HSVA float"),
                                 GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (gi, output, result, 0, babl_format ("HSVA float"),
                            GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (gi))
    {
      gfloat *in  = gi->data[0];
      gfloat *out = gi->data[1];
      gint    i;

      for (i = 0; i < gi->length; i++)
        {
          out[0] = in[0]; /* Keep hue */
          out[1] = (in[1] - data.slo) / data.sdiff;
          out[2] = (in[2] - data.vlo) / data.vdiff;
          out[3] = in[3]; /* Keep alpha */

          in  += 4;
          out += 4;
        }
    }

  return TRUE;
}
Exemple #26
0
void
gimp_gegl_index_to_mask (GeglBuffer          *indexed_buffer,
                         const GeglRectangle *indexed_rect,
                         const Babl          *indexed_format,
                         GeglBuffer          *mask_buffer,
                         const GeglRectangle *mask_rect,
                         gint                 index)
{
  GeglBufferIterator *iter;

  iter = gegl_buffer_iterator_new (indexed_buffer, indexed_rect, 0,
                                   indexed_format,
                                   GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, mask_buffer, mask_rect, 0,
                            babl_format ("Y float"),
                            GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      const guchar *indexed = iter->data[0];
      gfloat       *mask    = iter->data[1];
      gint          count   = iter->length;

      while (count--)
        {
          if (*indexed == index)
            *mask = 1.0;
          else
            *mask = 0.0;

          indexed++;
          mask++;
        }
    }
}
Exemple #27
0
static void
render_blob (GeglBuffer    *buffer,
             GeglRectangle *rect,
             GimpBlob      *blob)
{
  GeglBufferIterator *iter;
  GeglRectangle      *roi;

  iter = gegl_buffer_iterator_new (buffer, rect, 0, babl_format ("Y u8"),
                                   GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
  roi = &iter->roi[0];

  while (gegl_buffer_iterator_next (iter))
    {
      guchar *d = iter->data[0];
      gint    h = roi->height;
      gint    y;

      for (y = 0; y < h; y++, d += roi->width * 1)
        {
          render_blob_line (blob, d, roi->x, roi->y + y, roi->width);
        }
    }
}
static void
gimp_image_convert_profile_rgb (GimpImage                *image,
                                GimpColorProfile         *src_profile,
                                GimpColorProfile         *dest_profile,
                                GimpColorRenderingIntent  intent,
                                gboolean                  bpc,
                                GimpProgress             *progress)
{
  GList *layers;
  GList *list;
  gint   n_drawables;
  gint   nth_drawable;

  layers = gimp_image_get_layer_list (image);

  n_drawables = g_list_length (layers);

  for (list = layers, nth_drawable = 0;
       list;
       list = g_list_next (list), nth_drawable++)
    {
      GimpDrawable    *drawable = list->data;
      cmsHPROFILE      src_lcms;
      cmsHPROFILE      dest_lcms;
      const Babl      *iter_format;
      cmsUInt32Number  lcms_format;
      cmsUInt32Number  flags;
      cmsHTRANSFORM    transform;

      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        continue;

      src_lcms  = gimp_color_profile_get_lcms_profile (src_profile);
      dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);

      iter_format =
        gimp_color_profile_get_format (gimp_drawable_get_format (drawable),
                                       &lcms_format);

      flags = cmsFLAGS_NOOPTIMIZE;

      if (bpc)
        flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

      transform = cmsCreateTransform (src_lcms,  lcms_format,
                                      dest_lcms, lcms_format,
                                      intent, flags);

      if (transform)
        {
          GeglBuffer         *buffer;
          GeglBufferIterator *iter;

          buffer = gimp_drawable_get_buffer (drawable);

          gimp_drawable_push_undo (drawable, NULL, NULL,
                                   0, 0,
                                   gegl_buffer_get_width  (buffer),
                                   gegl_buffer_get_height (buffer));

          iter = gegl_buffer_iterator_new (buffer, NULL, 0,
                                           iter_format,
                                           GEGL_ACCESS_READWRITE,
                                           GEGL_ABYSS_NONE);

          while (gegl_buffer_iterator_next (iter))
            {
              cmsDoTransform (transform,
                              iter->data[0], iter->data[0], iter->length);
            }

          gimp_drawable_update (drawable, 0, 0,
                                gegl_buffer_get_width  (buffer),
                                gegl_buffer_get_height (buffer));

          cmsDeleteTransform (transform);
        }

      if (progress)
        gimp_progress_set_value (progress,
                                 (gdouble) nth_drawable / (gdouble) n_drawables);
    }

  g_list_free (layers);
}
static GeglBuffer *
gradient_precalc_shapeburst (GimpImage           *image,
                             GimpDrawable        *drawable,
                             const GeglRectangle *region,
                             gdouble              dist,
                             GimpProgress        *progress)
{
  GimpChannel *mask;
  GeglBuffer  *dist_buffer;
  GeglBuffer  *temp_buffer;
  GeglNode    *shapeburst;
  gdouble      max;
  gfloat       max_iteration;

  gimp_progress_set_text (progress, _("Calculating distance map"));

  /*  allocate the distance map  */
  dist_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                 region->width, region->height),
                                 babl_format ("Y float"));

  /*  allocate the selection mask copy
   *  XXX: its format should be the same of gimp:shapeburst input buffer
   *       porting the op to 'float' should be reflected here as well
   */
  temp_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                 region->width, region->height),
                                 babl_format ("Y u8"));

  mask = gimp_image_get_mask (image);

  /*  If the image mask is not empty, use it as the shape burst source  */
  if (! gimp_channel_is_empty (mask))
    {
      gint x, y, width, height;
      gint off_x, off_y;

      gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);
      gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);

      /*  copy the mask to the temp mask  */
      gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
                        GEGL_RECTANGLE (x + off_x, y + off_y, width, height),
                        temp_buffer,
                        GEGL_RECTANGLE (0, 0, 0, 0));
    }
  else
    {
      /*  If the intended drawable has an alpha channel, use that  */
      if (gimp_drawable_has_alpha (drawable))
        {
          const Babl *component_format;

          component_format = babl_format ("A u8");

          /*  extract the aplha into the temp mask  */
          gegl_buffer_set_format (temp_buffer, component_format);
          gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
                            GEGL_RECTANGLE (region->x, region->y,
                                            region->width, region->height),
                            temp_buffer,
                            GEGL_RECTANGLE (0, 0, 0, 0));
          gegl_buffer_set_format (temp_buffer, NULL);
        }
      else
        {
          GeglColor *white = gegl_color_new ("white");

          /*  Otherwise, just fill the shapeburst to white  */
          gegl_buffer_set_color (temp_buffer, NULL, white);
          g_object_unref (white);
        }
    }

  shapeburst = gegl_node_new_child (NULL,
                                    "operation", "gimp:shapeburst",
                                    NULL);

  gimp_gegl_progress_connect (shapeburst, progress, NULL);

  gimp_gegl_apply_operation (temp_buffer, NULL, NULL,
                             shapeburst,
                             dist_buffer, NULL);

  gegl_node_get (shapeburst, "max-iterations", &max, NULL);

  g_object_unref (shapeburst);

  max_iteration = max;

  g_object_unref (temp_buffer);

  /*  normalize the shapeburst with the max iteration  */
  if (max_iteration > 0)
    {
      GeglBufferIterator *iter;

      iter = gegl_buffer_iterator_new (dist_buffer, NULL, 0, NULL,
                                       GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (iter))
        {
          gint    count = iter->length;
          gfloat *data  = iter->data[0];

          while (count--)
            *data++ /= max_iteration;
        }
    }

  return dist_buffer;
}
static gboolean
gimp_operation_cage_coef_calc_process (GeglOperation       *operation,
                                       GeglBuffer          *output,
                                       const GeglRectangle *roi)
{
  GimpOperationCageCoefCalc *occc   = GIMP_OPERATION_CAGE_COEF_CALC (operation);
  GimpCageConfig            *config = GIMP_CAGE_CONFIG (occc->config);

  Babl *format = babl_format_n (babl_type ("float"), 2 * gimp_cage_config_get_n_points (config));

  GeglBufferIterator *it;
  guint               n_cage_vertices;
  GimpCagePoint      *current, *last;

  if (! config)
    return FALSE;

  n_cage_vertices   = gimp_cage_config_get_n_points (config);

  it = gegl_buffer_iterator_new (output, roi, format, GEGL_BUFFER_READWRITE);

  while (gegl_buffer_iterator_next (it))
    {
      /* iterate inside the roi */
      gint  n_pixels = it->length;
      gint  x = it->roi->x; /* initial x                   */
      gint  y = it->roi->y; /*           and y coordinates */
      gint  j;

      gfloat      *coef = it->data[0];

      while(n_pixels--)
        {
          if (gimp_cage_config_point_inside(config, x, y))
            {
              last = &(g_array_index (config->cage_points, GimpCagePoint, 0));

              for( j = 0; j < n_cage_vertices; j++)
                {
                  GimpVector2 v1,v2,a,b,p;
                  gdouble BA,SRT,L0,L1,A0,A1,A10,L10, Q,S,R, absa;

                  current = &(g_array_index (config->cage_points, GimpCagePoint, (j+1) % n_cage_vertices));
                  v1 = last->src_point;
                  v2 = current->src_point;
                  p.x = x;
                  p.y = y;
                  a.x = v2.x - v1.x;
                  a.y = v2.y - v1.y;
                  absa = gimp_vector2_length (&a);

                  b.x = v1.x - x;
                  b.y = v1.y - y;
                  Q = a.x * a.x + a.y * a.y;
                  S = b.x * b.x + b.y * b.y;
                  R = 2.0 * (a.x * b.x + a.y * b.y);
                  BA = b.x * a.y - b.y * a.x;
                  SRT = sqrt(4.0 * S * Q - R * R);

                  L0 = log(S);
                  L1 = log(S + Q + R);
                  A0 = atan2(R, SRT) / SRT;
                  A1 = atan2(2.0 * Q + R, SRT) / SRT;
                  A10 = A1 - A0;
                  L10 = L1 - L0;

                  /* edge coef */
                  coef[j + n_cage_vertices] = (-absa / (4.0 * G_PI)) * ((4.0*S-(R*R)/Q) * A10 + (R / (2.0 * Q)) * L10 + L1 - 2.0);

                  if (isnan(coef[j + n_cage_vertices]))
                    {
                      coef[j + n_cage_vertices] = 0.0;
                    }

                  /* vertice coef */
                  if (!gimp_operation_cage_coef_calc_is_on_straight (&v1, &v2, &p))
                    {
                      coef[j] += (BA / (2.0 * G_PI)) * (L10 /(2.0*Q) - A10 * (2.0 + R / Q));
                      coef[(j+1)%n_cage_vertices] -= (BA / (2.0 * G_PI)) * (L10 / (2.0 * Q) - A10 * (R / Q));
                    }

                  last = current;
                }
            }

          coef += 2 * n_cage_vertices;

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

  return TRUE;
}