Beispiel #1
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties    *o = GEGL_PROPERTIES (operation);
  gint           size, i, pos;
  GeglRectangle  dst_rect;


  if (o->direction == GEGL_ORIENTATION_HORIZONTAL)
    {
      size = result->height;
      dst_rect.width  = result->width;
      dst_rect.height = 1;
      pos = result->y;
    }
  else
    {
      size = result->width;
      dst_rect.width  = 1;
      dst_rect.height = result->height;
      pos = result->x;
    }

  dst_rect.x = result->x;
  dst_rect.y = result->y;

  for (i = 0; i < size; i++)
    {
      GeglRectangle src_rect;
      gint shift = gegl_random_int_range (o->rand, i + pos, 0, 0, 0,
                                          -o->shift, o->shift + 1);

      if (o->direction == GEGL_ORIENTATION_HORIZONTAL)
        {
          dst_rect.y = i + result->y;
          src_rect = dst_rect;
          src_rect.x = result->x + shift;
        }
      else
        {
          dst_rect.x = i + result->x;
          src_rect = dst_rect;
          src_rect.y = result->y + shift;
        }

      /* XXX: gegl_buffer_copy doesn't allow to set the abyss policy,
       * but we probably need _CLAMP here */
      gegl_buffer_copy (input, &src_rect, output, &dst_rect);
    }

  return  TRUE;
}
Beispiel #2
0
static void
calculate_bleed (GeglOperation *operation,
                 GeglBuffer    *input)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle rectA, rectB;
  GeglBufferIterator *iter;
  gfloat max_length = (gfloat) o->strength;
  gfloat threshold  = o->threshold;
  GHashTable *bleed_table = o->chant_data;

  rectA = *gegl_operation_source_get_bounding_box (operation, "input");
  rectA.width -= 3;
  rectB = rectA;
  rectB.x += 3;

  if (rectA.width <= 0)
    return;

  iter = gegl_buffer_iterator_new (input,
                                   &rectA,
                                   0,
                                   babl_format ("RGBA float"),
                                   GEGL_BUFFER_READ,
                                   GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter,
                            input,
                            &rectB,
                            0,
                            babl_format ("RGBA float"),
                            GEGL_BUFFER_READ,
                            GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gint ix, iy;
      gfloat *pixelsA = (gfloat *)iter->data[0];
      gfloat *pixelsB = (gfloat *)iter->data[1];

      for (ix = 0; ix < iter->roi[0].width; ix++)
        for (iy = 0; iy < iter->roi[0].height; iy++)
          {
            gint idx = iy * iter->roi[0].width + ix * 4;
            if (threshold_exceeded (&pixelsA[idx], &pixelsB[idx], threshold))
              {
                gint x = ix + iter->roi[0].x;
                gint y = iy + iter->roi[0].y;
                pair *k = g_new (pair, 1);
                gint *v = g_new (gint, 1);
                gint bleed_length = 1 + gegl_random_int_range (o->rand, x, y, 0, 0, 0, max_length);

                k->x = x;
                k->y = y;

                *v = bleed_length;
                g_hash_table_insert (bleed_table, k, v);
              }
          }
    }
}
Beispiel #3
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglBuffer              *tmp;
  gfloat                  *src_buf;
  gfloat                  *dst_buf;
  gfloat                  *in_pixel;
  gfloat                  *out_pixel;
  gint                     n_pixels = result->width * result->height;
  gint                     width    = result->width;
  GeglRectangle            src_rect;
  gint                     total_pixels;
  gint                     i;

  tmp = gegl_buffer_new (result, babl_format ("RGBA float"));

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

  total_pixels = src_rect.height * src_rect.width;

  src_buf = g_slice_alloc (4 * total_pixels * sizeof (gfloat));
  dst_buf = g_slice_alloc (4 * n_pixels * sizeof (gfloat));

  gegl_buffer_copy (input, NULL, tmp, NULL);

  for (i = 0; i < o->repeat; i++)
    {
      gint x, y, n;

      x = result->x;
      y = result->y;
      n = 0;

      n_pixels = result->width * result->height;

      gegl_buffer_get (tmp, &src_rect, 1.0,
                       babl_format ("RGBA float"), src_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

      in_pixel  = src_buf + (src_rect.width + 1) * 4;
      out_pixel = dst_buf;

      while (n_pixels--)
        {
          gint b;

          if (gegl_random_double_range (o->seed, x, y, 0, n++, 0.0, 100.0) <=
              o->pct_random)
            {
              gint k = gegl_random_int_range (o->seed, x, y, 0, n++, 0, 9);

              for (b = 0; b < 4; b++)
                {
                  switch (k)
                    {
                    case 0:
                      out_pixel[b] = in_pixel[b - src_rect.width * 4 - 4];
                      break;
                    case 1:
                      out_pixel[b] = in_pixel[b - src_rect.width * 4];
                      break;
                    case 2:
                      out_pixel[b] = in_pixel[b - src_rect.width * 4 + 4];
                      break;
                    case 3:
                      out_pixel[b] = in_pixel[b - 4];
                      break;
                    case 4:
                      out_pixel[b] = in_pixel[b];
                      break;
                    case 5:
                      out_pixel[b] = in_pixel[b + 4];
                      break;
                    case 6:
                      out_pixel[b] = in_pixel[b + src_rect.width * 4 - 4];
                      break;
                    case 7:
                      out_pixel[b] = in_pixel[b + src_rect.width * 4];
                      break;
                    case 8:
                      out_pixel[b] = in_pixel[b + src_rect.width * 4 + 4];
                      break;
                    }
                }
            }
          else
            {
              for (b = 0; b < 4; b++)
                {
                  out_pixel[b] = in_pixel[b];
                }
            }

          if (n_pixels % width == 0)
            in_pixel += 12;
          else
            in_pixel += 4;

          out_pixel += 4;

          x++;
          if (x >= result->x + result->width)
            {
              x = result->x;
              y++;
            }
        }

      gegl_buffer_set (tmp, result, 0,
                       babl_format ("RGBA float"), dst_buf,
                       GEGL_AUTO_ROWSTRIDE);
    }

  gegl_buffer_copy (tmp, NULL, output, NULL);

  g_slice_free1 (4 * total_pixels * sizeof (gfloat), src_buf);
  g_slice_free1 (4 * n_pixels * sizeof (gfloat), dst_buf);

  return TRUE;
}