Exemplo n.º 1
0
static int
test (void)
{
  int   components;
  int   OK = 1;

  for (components = 1; components < 2048; components ++)
  {
    const Babl *fish;
    const Babl *src_fmt;
    const Babl *dst_fmt;
    int   i;

    src_fmt = babl_format_n (babl_type ("float"), components);
    dst_fmt = babl_format_n (babl_type ("u8"), components);

    fish = babl_fish (src_fmt, dst_fmt);

    babl_process (fish, source_buf, destination_buf, PIXELS);

    for (i = 0; i < PIXELS * components; i++)
      {
        if (abs (destination_buf[i] - reference_buf[i]) > TOLERANCE)
          {
            babl_log ("%i-components, pixel %i component %i is %i should be %i",
                      components, i / components, i % components, destination_buf[i], reference_buf[i]);
            OK = 0;
          }
      }
  }
  if (!OK)
    return -1;
  return 0;
}
Exemplo n.º 2
0
static void
gimp_operation_cage_transform_prepare (GeglOperation *operation)
{
  GimpOperationCageTransform *oct    = GIMP_OPERATION_CAGE_TRANSFORM (operation);
  GimpCageConfig             *config = GIMP_CAGE_CONFIG (oct->config);

  gegl_operation_set_format (operation, "input",
                             babl_format_n (babl_type ("float"),
                                            2 * gimp_cage_config_get_n_points (config)));
  gegl_operation_set_format (operation, "output",
                             babl_format_n (babl_type ("float"), 2));
}
Exemplo n.º 3
0
static void
gimp_cage_tool_compute_coef (GimpCageTool *ct)
{
  GimpCageConfig *config = ct->config;
  GimpProgress   *progress;
  const Babl     *format;
  GeglNode       *gegl;
  GeglNode       *input;
  GeglNode       *output;
  GeglProcessor  *processor;
  GeglBuffer     *buffer;
  gdouble         value;

  progress = gimp_progress_start (GIMP_PROGRESS (ct),
                                  _("Computing Cage Coefficients"), FALSE);

  if (ct->coef)
    {
      g_object_unref (ct->coef);
      ct->coef = NULL;
    }

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


  gegl = gegl_node_new ();

  input = gegl_node_new_child (gegl,
                               "operation", "gimp:cage-coef-calc",
                               "config",    ct->config,
                               NULL);

  output = gegl_node_new_child (gegl,
                                "operation", "gegl:buffer-sink",
                                "buffer",    &buffer,
                                "format",    format,
                                NULL);

  gegl_node_connect_to (input, "output",
                        output, "input");

  processor = gegl_node_new_processor (output, NULL);

  while (gegl_processor_work (processor, &value))
    {
      if (progress)
        gimp_progress_set_value (progress, value);
    }

  if (progress)
    gimp_progress_end (progress);

  g_object_unref (processor);

  ct->coef = buffer;
  g_object_unref (gegl);

  ct->dirty_coef = FALSE;
}
Exemplo n.º 4
0
static void
gimp_warp_tool_start (GimpWarpTool *wt,
                      GimpDisplay  *display)
{
  GimpTool      *tool     = GIMP_TOOL (wt);
  GimpImage     *image    = gimp_display_get_image (display);
  GimpDrawable  *drawable = gimp_image_get_active_drawable (image);
  const Babl    *format;
  GeglRectangle  bbox;

  tool->display  = display;
  tool->drawable = drawable;

  /* Create the coords buffer, with the size of the selection */
  format = babl_format_n (babl_type ("float"), 2);

  gimp_item_mask_intersect (GIMP_ITEM (drawable), &bbox.x, &bbox.y,
                            &bbox.width, &bbox.height);

#ifdef WARP_DEBUG
  g_printerr ("Initialize coordinate buffer (%d,%d) at %d,%d\n",
              bbox.width, bbox.height, bbox.x, bbox.y);
#endif

  wt->coords_buffer = gegl_buffer_new (&bbox, format);

  gimp_warp_tool_create_image_map (wt, drawable);

  if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (wt)))
    gimp_draw_tool_start (GIMP_DRAW_TOOL (wt), display);
}
Exemplo n.º 5
0
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *src_format   = gegl_operation_get_source_format (operation, "input");
  const Babl *input_format = babl_format ("RGB double");
  gint        n_components = 3;
  const Babl *output_format;

  if (src_format)
    {
      const Babl *model = babl_format_get_model (src_format);

      if (model == babl_model ("RGB") || model == babl_model ("R'G'B'") ||
          model == babl_model ("RGBA") || model == babl_model ("R'G'B'A"))
        {
          input_format = babl_format ("RGB double");
          n_components = 3;
        }
      else if (model == babl_model ("Y") || model == babl_model ("Y'") ||
               model == babl_model ("YA") || model == babl_model ("Y'A"))
        {
          input_format = babl_format ("Y double");
          n_components = 1;
        }
    }

  if (o->squared)
    n_components *= 2;

  output_format = babl_format_n (babl_type ("double"), n_components);

  gegl_operation_set_format (operation, "input", input_format);
  gegl_operation_set_format (operation, "output", output_format);
}
Exemplo n.º 6
0
static void
prepare (GeglOperation *operation)
{
  const Babl *format = babl_format ("RGBA float");

  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "aux", babl_format_n (babl_type ("float"), 2));
  gegl_operation_set_format (operation, "output", format);
}
static void
gimp_operation_scalar_multiply_prepare (GeglOperation *operation)
{
  GimpOperationScalarMultiply *self = GIMP_OPERATION_SCALAR_MULTIPLY (operation);
  const Babl                  *format;

  format = babl_format_n (babl_type ("float"), self->n_components);

  gegl_operation_set_format (operation, "input",  format);
  gegl_operation_set_format (operation, "output", format);
}
Exemplo n.º 8
0
static void
gimp_operation_cage_coef_calc_prepare (GeglOperation *operation)
{
  GimpOperationCageCoefCalc *occc   = GIMP_OPERATION_CAGE_COEF_CALC (operation);
  GimpCageConfig            *config = GIMP_CAGE_CONFIG (occc->config);

  gegl_operation_set_format (operation,
                             "output",
                             babl_format_n (babl_type ("float"),
                                            2 * gimp_cage_config_get_n_points (config)));
}
Exemplo n.º 9
0
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);

  const Babl *format = babl_format_n (babl_type ("float"), 2);
  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "output", format);

  if (!o->user_data)
    o->user_data = g_slice_new0 (WarpPrivate);
}
Exemplo n.º 10
0
int
main (int    argc,
      char **argv)
{
    int OK = 1;
    babl_init ();
    OK = ! babl_format_is_palette (babl_format_n (babl_type ("double"), 3));
    if(1) {
        unsigned char in[][1]   = {{        0},{          1},{          2},{15}};
        unsigned char out[][4]  = {{0,0,0,255},{127,0,0,255},{0,127,0,255},{255,255,255,255}};
        const Babl *palA;// = babl_new_palette (NULL, 0);
        //Babl *palB = babl_new_palette (NULL, 0);
        //
        babl_new_palette (NULL, &palA, NULL);
        assert (palA);

        CHECK_CONV("pal to rgba", unsigned char,
                   palA, babl_format("RGBA u8"),
                   in, out);
    }
Exemplo n.º 11
0
static void
prepare (GeglOperation *operation)
{
  GeglChantO  *o = GEGL_CHANT_PROPERTIES (operation);
  WarpPrivate *priv;

  const Babl *format = babl_format_n (babl_type ("float"), 2);
  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "output", format);

  if (!o->chant_data)
    {
      o->chant_data = g_slice_new (WarpPrivate);
    }

  priv = (WarpPrivate*) o->chant_data;
  priv->last_point_set = FALSE;
  priv->lookup = NULL;
  priv->buffer = NULL;
}
Exemplo n.º 12
0
static void
gimp_warp_tool_start (GimpWarpTool *wt,
                      GimpDisplay  *display)
{
  GimpTool        *tool     = GIMP_TOOL (wt);
  GimpWarpOptions *options  = GIMP_WARP_TOOL_GET_OPTIONS (wt);
  GimpImage       *image    = gimp_display_get_image (display);
  GimpDrawable    *drawable = gimp_image_get_active_drawable (image);
  const Babl      *format;
  GeglRectangle    bbox;

  tool->display  = display;
  tool->drawable = drawable;

  /* Create the coords buffer, with the size of the selection */
  format = babl_format_n (babl_type ("float"), 2);

  gimp_item_mask_intersect (GIMP_ITEM (drawable), &bbox.x, &bbox.y,
                            &bbox.width, &bbox.height);

#ifdef WARP_DEBUG
  g_printerr ("Initialize coordinate buffer (%d,%d) at %d,%d\n",
              bbox.width, bbox.height, bbox.x, bbox.y);
#endif

  wt->coords_buffer = gegl_buffer_new (&bbox, format);

  gimp_warp_tool_create_image_map (wt, drawable);

  if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (wt)))
    gimp_draw_tool_start (GIMP_DRAW_TOOL (wt), display);

  if (options->animate_button)
    {
      g_signal_connect_swapped (options->animate_button, "clicked",
                                G_CALLBACK (gimp_warp_tool_animate),
                                wt);

      gtk_widget_set_sensitive (options->animate_button, TRUE);
    }
}
Exemplo n.º 13
0
static gboolean
gimp_operation_cage_transform_process (GeglOperation       *operation,
                                       GeglBuffer          *in_buf,
                                       GeglBuffer          *aux_buf,
                                       GeglBuffer          *out_buf,
                                       const GeglRectangle *roi,
                                       gint                 level)
{
  GimpOperationCageTransform *oct    = GIMP_OPERATION_CAGE_TRANSFORM (operation);
  GimpCageConfig             *config = GIMP_CAGE_CONFIG (oct->config);
  GeglRectangle               cage_bb;
  gfloat                     *coords;
  gfloat                     *coef;
  const Babl                 *format_coef;
  GimpVector2                 plain_color;
  GeglBufferIterator         *it;
  gint                        x, y;
  gboolean                    output_set;
  GimpCagePoint              *point;
  guint                       n_cage_vertices;

  /* pre-fill the out buffer with no-displacement coordinate */
  it      = gegl_buffer_iterator_new (out_buf, roi, 0, NULL, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
  cage_bb = gimp_cage_config_get_bounding_box (config);

  point = &(g_array_index (config->cage_points, GimpCagePoint, 0));
  plain_color.x = (gint) point->src_point.x;
  plain_color.y = (gint) point->src_point.y;

  n_cage_vertices   = gimp_cage_config_get_n_points (config);

  while (gegl_buffer_iterator_next (it))
    {
      /* iterate inside the roi */
      gint    n_pixels = it->length;
      gfloat *output   = it->data[0];

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

      while (n_pixels--)
        {
          output_set = FALSE;
          if (oct->fill_plain_color)
            {
              if (x > cage_bb.x &&
                  y > cage_bb.y &&
                  x < cage_bb.x + cage_bb.width &&
                  y < cage_bb.y + cage_bb.height)
                {
                  if (gimp_cage_config_point_inside (config, x, y))
                    {
                      output[0] = plain_color.x;
                      output[1] = plain_color.y;
                      output_set = TRUE;
                    }
                }
            }
          if (!output_set)
            {
              output[0] = x;
              output[1] = y;
            }

          output += 2;

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

  oct->progress = 0.0;
  g_object_notify (G_OBJECT (oct), "progress");

  /* pre-allocate memory outside of the loop */
  coords      = g_slice_alloc (2 * sizeof (gfloat));
  coef        = g_malloc (n_cage_vertices * 2 * sizeof (gfloat));
  format_coef = babl_format_n (babl_type ("float"), 2 * n_cage_vertices);

  /* compute, reverse and interpolate the transformation */
  for (y = cage_bb.y; y < cage_bb.y + cage_bb.height - 1; y++)
    {
      GimpVector2 p1_d, p2_d, p3_d, p4_d;
      GimpVector2 p1_s, p2_s, p3_s, p4_s;

      p1_s.y = y;
      p2_s.y = y+1;
      p3_s.y = y+1;
      p3_s.x = cage_bb.x;
      p4_s.y = y;
      p4_s.x = cage_bb.x;

      p3_d = gimp_cage_transform_compute_destination (config, coef, format_coef, aux_buf, p3_s);
      p4_d = gimp_cage_transform_compute_destination (config, coef, format_coef, aux_buf, p4_s);

      for (x = cage_bb.x; x < cage_bb.x + cage_bb.width - 1; x++)
        {
          p1_s = p4_s;
          p2_s = p3_s;
          p3_s.x = x+1;
          p4_s.x = x+1;

          p1_d = p4_d;
          p2_d = p3_d;
          p3_d = gimp_cage_transform_compute_destination (config, coef, format_coef, aux_buf, p3_s);
          p4_d = gimp_cage_transform_compute_destination (config, coef, format_coef, aux_buf, p4_s);

          if (gimp_cage_config_point_inside (config, x, y))
            {
              gimp_operation_cage_transform_interpolate_source_coords_recurs (oct,
                                                                              out_buf,
                                                                              roi,
                                                                              p1_s, p1_d,
                                                                              p2_s, p2_d,
                                                                              p3_s, p3_d,
                                                                              0,
                                                                              coords);

              gimp_operation_cage_transform_interpolate_source_coords_recurs (oct,
                                                                              out_buf,
                                                                              roi,
                                                                              p1_s, p1_d,
                                                                              p3_s, p3_d,
                                                                              p4_s, p4_d,
                                                                              0,
                                                                              coords);
            }
        }

      if ((y - cage_bb.y) % 20 == 0)
        {
          gdouble fraction = ((gdouble) (y - cage_bb.y) /
                              (gdouble) (cage_bb.height));

          /*  0.0 and 1.0 indicate progress start/end, so avoid them  */
          if (fraction > 0.0 && fraction < 1.0)
            {
              oct->progress = fraction;
              g_object_notify (G_OBJECT (oct), "progress");
            }
        }
    }

  g_free (coef);
  g_slice_free1 (2 * sizeof (gfloat), coords);

  oct->progress = 1.0;
  g_object_notify (G_OBJECT (oct), "progress");

  return TRUE;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
static void
stamp (GeglProperties *o,
       gdouble         x,
       gdouble         y)
{
  WarpPrivate         *priv = (WarpPrivate*) o->user_data;
  GeglBufferIterator  *it;
  const Babl          *format;
  gdouble              stamp_force, influence;
  gdouble              x_mean = 0.0;
  gdouble              y_mean = 0.0;
  gint                 x_iter, y_iter;
  GeglRectangle        area;
  const GeglRectangle *src_extent;
  gfloat              *srcbuf, *stampbuf;
  gint                 buf_rowstride = 0;
  gfloat               s = 0, c = 0;

  area.x = floor (x - o->size / 2.0);
  area.y = floor (y - o->size / 2.0);
  area.width   = ceil (x + o->size / 2.0);
  area.height  = ceil (y + o->size / 2.0);
  area.width  -= area.x;
  area.height -= area.y;

  format = babl_format_n (babl_type ("float"), 2);

  /* If needed, compute the mean deformation */
  if (o->behavior == GEGL_WARP_BEHAVIOR_SMOOTH)
    {
      gint pixel_count = 0;

      it = gegl_buffer_iterator_new (priv->buffer, &area, 0, format,
                                     GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (it))
        {
          gint    n_pixels    = it->length;
          gfloat *coords      = it->data[0];

          while (n_pixels--)
            {
              x_mean += coords[0];
              y_mean += coords[1];
              coords += 2;
            }
          pixel_count += it->roi->width * it->roi->height;
        }
      x_mean /= pixel_count;
      y_mean /= pixel_count;
    }
  else if (o->behavior == GEGL_WARP_BEHAVIOR_SWIRL_CW ||
           o->behavior == GEGL_WARP_BEHAVIOR_SWIRL_CCW)
    {
      /* swirl by 5 degrees per stamp (for strength 100).
       * not exactly sin/cos factors,
       * since we calculate an off-center offset-vector */

      /* note that this is fudged for stamp_force < 1.0 and
       * results in a slight upscaling there. It is a compromise
       * between exactness and calculation speed. */
      s = sin (0.01 * o->strength * 5.0 / 180 * G_PI);
      c = cos (0.01 * o->strength * 5.0 / 180 * G_PI) - 1.0;
    }

  srcbuf = gegl_buffer_linear_open (priv->buffer, NULL, &buf_rowstride, NULL);
  buf_rowstride /= sizeof (gfloat);
  src_extent = gegl_buffer_get_extent (priv->buffer);

  stampbuf = g_new0 (gfloat, 2 * area.height * area.width);

  for (y_iter = 0; y_iter < area.height; y_iter++)
    {
      for (x_iter = 0; x_iter < area.width; x_iter++)
        {
          gfloat nvx, nvy;
          gfloat xi, yi;
          gfloat *vals;
          gint dx, dy;
          gfloat weight_x, weight_y;
          gfloat *srcptr;

          xi = area.x + x_iter;
          xi += -x + 0.5;
          yi = area.y + y_iter;
          yi += -y + 0.5;

          stamp_force = get_stamp_force (o, xi, yi);
          influence = 0.01 * o->strength * stamp_force;

          switch (o->behavior)
            {
              case GEGL_WARP_BEHAVIOR_MOVE:
                nvx = influence * (priv->last_x - x);
                nvy = influence * (priv->last_y - y);
                break;
              case GEGL_WARP_BEHAVIOR_GROW:
                nvx = influence * -0.1 * xi;
                nvy = influence * -0.1 * yi;
                break;
              case GEGL_WARP_BEHAVIOR_SHRINK:
                nvx = influence * 0.1 * xi;
                nvy = influence * 0.1 * yi;
                break;
              case GEGL_WARP_BEHAVIOR_SWIRL_CW:
                nvx = stamp_force * ( c * xi + s * yi);
                nvy = stamp_force * (-s * xi + c * yi);
                break;
              case GEGL_WARP_BEHAVIOR_SWIRL_CCW:
                nvx = stamp_force * ( c * xi - s * yi);
                nvy = stamp_force * ( s * xi + c * yi);
                break;
              case GEGL_WARP_BEHAVIOR_ERASE:
              case GEGL_WARP_BEHAVIOR_SMOOTH:
              default:
                nvx = 0.0;
                nvy = 0.0;
                break;
            }

          vals = stampbuf + (y_iter * area.width + x_iter) * 2;

          dx = floorf (nvx);
          dy = floorf (nvy);

          if (area.x + x_iter + dx     <  src_extent->x                     ||
              area.x + x_iter + dx + 1 >= src_extent->x + src_extent->width ||
              area.y + y_iter + dy     <  src_extent->y                     ||
              area.y + y_iter + dy + 1 >= src_extent->y + src_extent->height)
            {
              continue;
            }

          srcptr = srcbuf + (area.y - src_extent->y + y_iter + dy) * buf_rowstride +
                            (area.x - src_extent->x + x_iter + dx) * 2;

          if (o->behavior == GEGL_WARP_BEHAVIOR_ERASE)
            {
              vals[0] = srcptr[0] * (1.0 - MIN (influence, 1.0));
              vals[1] = srcptr[1] * (1.0 - MIN (influence, 1.0));
            }
          else if (o->behavior == GEGL_WARP_BEHAVIOR_SMOOTH)
            {
              vals[0] = (1.0 - influence) * srcptr[0] + influence * x_mean;
              vals[1] = (1.0 - influence) * srcptr[1] + influence * y_mean;
            }
          else
            {
              weight_x = nvx - dx;
              weight_y = nvy - dy;

              /* bilinear interpolation of the vectors */

              vals[0]  = srcptr[0] * (1.0 - weight_x) * (1.0 - weight_y);
              vals[1]  = srcptr[1] * (1.0 - weight_x) * (1.0 - weight_y);

              vals[0] += srcptr[2] * weight_x * (1.0 - weight_y);
              vals[1] += srcptr[3] * weight_x * (1.0 - weight_y);

              vals[0] += srcptr[buf_rowstride + 0] * (1.0 - weight_x) * weight_y;
              vals[1] += srcptr[buf_rowstride + 1] * (1.0 - weight_x) * weight_y;

              vals[0] += srcptr[buf_rowstride + 2] * weight_x * weight_y;
              vals[1] += srcptr[buf_rowstride + 3] * weight_x * weight_y;

              vals[0] += nvx;
              vals[1] += nvy;
            }
        }
    }

  gegl_buffer_linear_close (priv->buffer, srcbuf);
  gegl_buffer_set (priv->buffer, &area, 0, format,
                   stampbuf, GEGL_AUTO_ROWSTRIDE);
  g_free (stampbuf);

  /* Memorize the stamp location for movement dependant behavior like move */
  priv->last_x = x;
  priv->last_y = y;
}
Exemplo n.º 16
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *aux,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties       *o = GEGL_PROPERTIES (operation);
  const Babl           *format_io, *format_coords;
  GeglSampler          *sampler;
  GeglBufferIterator   *it;
  gint                  index_in, index_out, index_coords;

  format_io = babl_format ("RGBA float");
  format_coords = babl_format_n (babl_type ("float"), 2);

  sampler = gegl_buffer_sampler_new_at_level (input, format_io, o->sampler_type, level);

  if (aux != NULL)
    {
      it = gegl_buffer_iterator_new (output, result, level, format_io,
                                     GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
      index_out = 0;

      index_coords = gegl_buffer_iterator_add (it, aux, result, level, format_coords,
                                               GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
      index_in = gegl_buffer_iterator_add (it, input, result, level, format_io,
                                           GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (it))
        {
          gint        i;
          gint        n_pixels = it->length;
          gint        x = it->roi->x; /* initial x                   */
          gint        y = it->roi->y; /*           and y coordinates */
          gdouble     scaling = GEGL_PROPERTIES (operation)->scaling;
          gfloat     *in = it->data[index_in];
          gfloat     *out = it->data[index_out];
          gfloat     *coords = it->data[index_coords];

          for (i=0; i<n_pixels; i++)
            {
              /* if the coordinate asked is an exact pixel, we fetch it
               * directly, to avoid the blur of sampling */
              if (coords[0] == 0 && coords[1] == 0)
                {
                  out[0] = in[0];
                  out[1] = in[1];
                  out[2] = in[2];
                  out[3] = in[3];
                }
              else
                {
                  gegl_sampler_get (sampler, x+coords[0] * scaling,
                                             y+coords[1] * scaling,
                                             NULL, out,
                                             GEGL_ABYSS_NONE);
                }

              coords += 2;
              in += 4;
              out += 4;

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

            }
        }
    }
  else
    {
      gegl_buffer_copy (input, result, GEGL_ABYSS_NONE,
                        output, result);
    }

  g_object_unref (sampler);

  return TRUE;
}
Exemplo n.º 17
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  cmsHTRANSFORM transform;
  const Babl *in_format, *out_format;

  gboolean alpha;
  gint bpp;

  in_format = babl_format_n (babl_type ("float"),
                 babl_format_get_n_components (gegl_buffer_get_format (input)));

  bpp = babl_format_get_bytes_per_pixel (in_format);

  /* create the transformation */
  {
    cmsHPROFILE in_profile, out_profile;
    cmsUInt32Number format;

    in_profile = o->src_profile;

    format = determine_lcms_format (in_format, in_profile);

    if (format == 0)
      return FALSE;

    if (format & EXTRA_SH (1))
      alpha = TRUE;
    else
      alpha = FALSE;

    out_profile = create_lcms_linear_rgb_profile ();

    transform = cmsCreateTransform (in_profile, format,
                                    out_profile, alpha ? TYPE_RGBA_FLT : TYPE_RGB_FLT,
                                    o->intent, o->black_point_compensation ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0);

    cmsCloseProfile (out_profile);
  }

  out_format = alpha ? babl_format ("RGBA float") : babl_format ("RGB float");

  /* iterate over the pixels */
  {
    GeglBufferIterator *gi;

    gi = gegl_buffer_iterator_new (input, result, 0, in_format,
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

    gegl_buffer_iterator_add (gi, output, result, 0, out_format,
                              GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);

    while (gegl_buffer_iterator_next (gi))
      {
        if (alpha)
          memcpy (gi->data[1], gi->data[0], bpp * gi->length);

        cmsDoTransform (transform, gi->data[0], gi->data[1], gi->length);
      }
  }

  cmsDeleteTransform (transform);

  return TRUE;
}
Exemplo n.º 18
0
static void
gimp_operation_cage_transform_init (GimpOperationCageTransform *self)
{
  self->format_coords = babl_format_n(babl_type("float"), 2);
}
Exemplo n.º 19
0
static void
stamp (GeglChantO          *o,
       const GeglRectangle *result,
       gdouble              x,
       gdouble              y)
{
  WarpPrivate         *priv = (WarpPrivate*) o->chant_data;
  GeglBufferIterator  *it;
  const Babl          *format;
  gdouble              influence;
  gdouble              x_mean = 0.0;
  gdouble              y_mean = 0.0;
  gint                 x_iter, y_iter;
  GeglRectangle        area = {x - o->size / 2.0,
                               y - o->size / 2.0,
                               o->size,
                               o->size};

  /* first point of the stroke */
  if (!priv->last_point_set)
    {
      priv->last_x = x;
      priv->last_y = y;
      priv->last_point_set = TRUE;
      return;
    }

  /* don't stamp if outside the roi treated */
  if (!gegl_rectangle_intersect (NULL, result, &area))
    return;

  format = babl_format_n (babl_type ("float"), 2);

  /* If needed, compute the mean deformation */
  if (o->behavior == GEGL_WARP_BEHAVIOR_SMOOTH)
    {
      gint pixel_count = 0;

      it = gegl_buffer_iterator_new (priv->buffer, &area, 0, format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (it))
        {
          gint    n_pixels    = it->length;
          gfloat *coords      = it->data[0];

          while (n_pixels--)
            {
              x_mean += coords[0];
              y_mean += coords[1];
              coords += 2;
            }
          pixel_count += it->roi->width * it->roi->height;
        }
      x_mean /= pixel_count;
      y_mean /= pixel_count;
    }

  it = gegl_buffer_iterator_new (priv->buffer, &area, 0, format, GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (it))
    {
      /* iterate inside the stamp roi */
      gint    n_pixels = it->length;
      gfloat *coords   = it->data[0];

      x_iter = it->roi->x; /* initial x         */
      y_iter = it->roi->y; /* and y coordinates */

      while (n_pixels--)
        {
          influence = 0.01 * o->strength * get_stamp_force (o,
                                                            x_iter - x,
                                                            y_iter - y);

          switch (o->behavior)
            {
              case GEGL_WARP_BEHAVIOR_MOVE:
                coords[0] += influence * (priv->last_x - x);
                coords[1] += influence * (priv->last_y - y);
                break;
              case GEGL_WARP_BEHAVIOR_GROW:
                coords[0] -= 2.0 * influence * (x_iter - x) / o->size;
                coords[1] -= 2.0 * influence * (y_iter - y) / o->size;
                break;
              case GEGL_WARP_BEHAVIOR_SHRINK:
                coords[0] += 2.0 * influence * (x_iter - x) / o->size;
                coords[1] += 2.0 * influence * (y_iter - y) / o->size;
                break;
              case GEGL_WARP_BEHAVIOR_SWIRL_CW:
                coords[0] += 3.0 * influence * (y_iter - y) / o->size;
                coords[1] -= 5.0 * influence * (x_iter - x) / o->size;
                break;
              case GEGL_WARP_BEHAVIOR_SWIRL_CCW:
                coords[0] -= 3.0 * influence * (y_iter - y) / o->size;
                coords[1] += 5.0 * influence * (x_iter - x) / o->size;
                break;
              case GEGL_WARP_BEHAVIOR_ERASE:
                coords[0] *= 1.0 - MIN (influence, 1.0);
                coords[1] *= 1.0 - MIN (influence, 1.0);
                break;
              case GEGL_WARP_BEHAVIOR_SMOOTH:
                coords[0] -= influence * (coords[0] - x_mean);
                coords[1] -= influence * (coords[1] - y_mean);
                break;
            }

          coords += 2;

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

  /* Memorize the stamp location for movement dependant behavior like move */
  priv->last_x = x;
  priv->last_y = y;
}
Exemplo n.º 20
0
static gboolean
gimp_warp_tool_start (GimpWarpTool *wt,
                      GimpDisplay  *display)
{
  GimpTool        *tool     = GIMP_TOOL (wt);
  GimpWarpOptions *options  = GIMP_WARP_TOOL_GET_OPTIONS (wt);
  GimpImage       *image    = gimp_display_get_image (display);
  GimpDrawable    *drawable = gimp_image_get_active_drawable (image);
  const Babl      *format;
  GeglRectangle    bbox;

  if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
    {
      gimp_tool_message_literal (tool, display,
                                 _("Cannot warp layer groups."));
      return FALSE;
    }

  if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
    {
      gimp_tool_message_literal (tool, display,
                                 _("The active layer's pixels are locked."));
      return FALSE;
    }

  if (! gimp_item_is_visible (GIMP_ITEM (drawable)))
    {
      gimp_tool_message_literal (tool, display,
                                 _("The active layer is not visible."));
      return FALSE;
    }

  tool->display  = display;
  tool->drawable = drawable;

  /* Create the coords buffer, with the size of the selection */
  format = babl_format_n (babl_type ("float"), 2);

  gimp_item_mask_intersect (GIMP_ITEM (drawable), &bbox.x, &bbox.y,
                            &bbox.width, &bbox.height);

#ifdef WARP_DEBUG
  g_printerr ("Initialize coordinate buffer (%d,%d) at %d,%d\n",
              bbox.width, bbox.height, bbox.x, bbox.y);
#endif

  wt->coords_buffer = gegl_buffer_new (&bbox, format);

  gimp_warp_tool_create_filter (wt, drawable);

  if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (wt)))
    gimp_draw_tool_start (GIMP_DRAW_TOOL (wt), display);

  if (options->animate_button)
    {
      g_signal_connect_swapped (options->animate_button, "clicked",
                                G_CALLBACK (gimp_warp_tool_animate),
                                wt);

      gtk_widget_set_sensitive (options->animate_button, TRUE);
    }

  return TRUE;
}