Ejemplo n.º 1
0
static int
test_buffer_cast (void)
{
  gint result = SUCCESS;
  GeglBuffer *buffer = gegl_buffer_new (GEGL_RECTANGLE (0,0,1,1),
                                         babl_format ("R'G'B'A u8"));
  GeglBuffer *cbuffer = gegl_buffer_new (GEGL_RECTANGLE (0,0,1,1),
                                         babl_format ("Y u8"));
  guchar srcpix[4] = {1,2,3,4};
  guchar dstpix[4] = {0};

  gegl_buffer_set (buffer, NULL, 0, NULL, srcpix, GEGL_AUTO_ROWSTRIDE);

  gegl_buffer_set_format (cbuffer, 
       babl_format_new ("name", "B' u8",
                          babl_model ("R'G'B'A"),
                          babl_type ("u8"),
                          babl_component ("B'"),
                          NULL));
  gegl_buffer_copy (buffer, NULL, cbuffer, NULL);
  gegl_buffer_set_format (cbuffer, NULL);

  gegl_buffer_get (cbuffer, NULL, 1.0, NULL,
      dstpix, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  if (dstpix[0] != 3)
    result = FAILURE;
  
  g_object_unref (buffer);
  g_object_unref (cbuffer);
  return result;
}
Ejemplo n.º 2
0
static GimpTempBuf *
gimp_pattern_get_new_preview (GimpViewable *viewable,
                              GimpContext  *context,
                              gint          width,
                              gint          height)
{
  GimpPattern *pattern = GIMP_PATTERN (viewable);
  GimpTempBuf *temp_buf;
  GeglBuffer  *src_buffer;
  GeglBuffer  *dest_buffer;
  gint         copy_width;
  gint         copy_height;

  copy_width  = MIN (width,  gimp_temp_buf_get_width  (pattern->mask));
  copy_height = MIN (height, gimp_temp_buf_get_height (pattern->mask));

  temp_buf = gimp_temp_buf_new (copy_width, copy_height,
                                gimp_temp_buf_get_format (pattern->mask));

  src_buffer  = gimp_temp_buf_create_buffer (pattern->mask);
  dest_buffer = gimp_temp_buf_create_buffer (temp_buf);

  gegl_buffer_copy (src_buffer,  GEGL_RECTANGLE (0, 0, copy_width, copy_height),
                    GEGL_ABYSS_NONE,
                    dest_buffer, GEGL_RECTANGLE (0, 0, 0, 0));

  g_object_unref (src_buffer);
  g_object_unref (dest_buffer);

  return temp_buf;
}
Ejemplo n.º 3
0
static gboolean gegl_operation_temporal_process (GeglOperation       *self,
                                                 GeglBuffer          *input,
                                                 GeglBuffer          *output,
                                                 const GeglRectangle *result,
                                                 gint                 level)
{
  GeglOperationTemporal *temporal = GEGL_OPERATION_TEMPORAL (self);
  GeglOperationTemporalPrivate *priv = temporal->priv;
  GeglOperationTemporalClass *temporal_class;

  temporal_class = GEGL_OPERATION_TEMPORAL_GET_CLASS (self);

  priv->width  = result->width;
  priv->height = result->height;

  {
   GeglRectangle write_rect = *result;
   write_rect.y = priv->next_to_write * priv->height;

   gegl_buffer_copy (input, result, priv->frame_store, &write_rect);
   priv->count++;
   priv->next_to_write++;
   if (priv->next_to_write >= priv->history_length)
     priv->next_to_write=0;
  }

 if (temporal_class->process)
   return temporal_class->process (self, input, output, result, level);
 return FALSE;
}
Ejemplo n.º 4
0
static void
gimp_text_layer_render_layout (GimpTextLayer  *layer,
                               GimpTextLayout *layout)
{
  GimpDrawable    *drawable = GIMP_DRAWABLE (layer);
  GimpItem        *item     = GIMP_ITEM (layer);
  GeglBuffer      *buffer;
  cairo_t         *cr;
  cairo_surface_t *surface;
  gint             width;
  gint             height;

  g_return_if_fail (gimp_drawable_has_alpha (drawable));

  width  = gimp_item_get_width  (item);
  height = gimp_item_get_height (item);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);

  cr = cairo_create (surface);
  gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
  cairo_destroy (cr);

  cairo_surface_flush (surface);

  buffer = gimp_cairo_surface_create_buffer (surface);

  gegl_buffer_copy (buffer, NULL,
                    gimp_drawable_get_buffer (drawable), NULL);

  g_object_unref (buffer);
  cairo_surface_destroy (surface);

  gimp_drawable_update (drawable, 0, 0, width, height);
}
Ejemplo n.º 5
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle compute;

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

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

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

  return  TRUE;
}
Ejemplo n.º 6
0
static void
gimp_layer_new_convert_buffer (GimpLayer         *layer,
                               GeglBuffer        *src_buffer,
                               GimpColorProfile  *src_profile,
                               GError           **error)
{
  GimpDrawable     *drawable    = GIMP_DRAWABLE (layer);
  GimpImage        *image       = gimp_item_get_image (GIMP_ITEM (layer));
  GimpColorConfig  *config      = image->gimp->config->color_management;
  GeglBuffer       *dest_buffer = gimp_drawable_get_buffer (drawable);
  GimpColorProfile *dest_profile;

  dest_profile =
    gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));

  if (! src_profile  ||
      ! dest_profile ||

      /*  FIXME: this is the wrong check, need something like file import
       *  conversion config
       */
      config->mode == GIMP_COLOR_MANAGEMENT_OFF)
    {
      gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL);
      return;
    }

  gimp_gegl_convert_color_profile (src_buffer,  NULL, src_profile,
                                   dest_buffer, NULL, dest_profile,
                                   GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
                                   TRUE, NULL);
}
Ejemplo n.º 7
0
static void
gimp_mask_undo_constructed (GObject *object)
{
  GimpMaskUndo *mask_undo = GIMP_MASK_UNDO (object);
  GimpChannel  *channel;
  GimpDrawable *drawable;
  gint          x1, y1, x2, y2;

  if (G_OBJECT_CLASS (parent_class)->constructed)
    G_OBJECT_CLASS (parent_class)->constructed (object);

  g_assert (GIMP_IS_CHANNEL (GIMP_ITEM_UNDO (object)->item));

  channel  = GIMP_CHANNEL (GIMP_ITEM_UNDO (object)->item);
  drawable = GIMP_DRAWABLE (channel);

  if (gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
    {
      mask_undo->buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                           x2 - x1, y2 - y1),
                                           gimp_drawable_get_format (drawable));

      gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
                        GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
                        mask_undo->buffer,
                        GEGL_RECTANGLE (0, 0, 0, 0));

      mask_undo->x = x1;
      mask_undo->y = y1;
    }

  mask_undo->format = gimp_drawable_get_format (drawable);
}
Ejemplo n.º 8
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gboolean need_fill = FALSE;
  gdouble r,g,b,a;

  if (input)
    {
      gegl_buffer_copy (input, result, output, result);
    }
  else
    {
      gegl_buffer_clear (output, result);
    }


  if (o->opacity > 0.0001 && o->color)
    {
      gegl_color_get_rgba (o->color, &r,&g,&b,&a);
      a *= o->opacity;
      if (a>0.001)
          need_fill=TRUE;
    }

  if (need_fill)
    {
      GStaticMutex mutex = G_STATIC_MUTEX_INIT;
      cairo_t *cr;
      cairo_surface_t *surface;
      guchar *data;


      g_static_mutex_lock (&mutex);
      data = (void*)gegl_buffer_linear_open (output, result, NULL, babl_format ("B'aG'aR'aA u8"));
      surface = cairo_image_surface_create_for_data (data,
                                                     CAIRO_FORMAT_ARGB32,
                                                     result->width,
                                                     result->height,
                                                     result->width * 4);

      cr = cairo_create (surface);
      cairo_translate (cr, -result->x, -result->y);
      if (g_str_equal (o->fill_rule, "evenodd"))
          cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);

      gegl_path_cairo_play (o->d, cr);
      cairo_set_source_rgba (cr, r,g,b,a);
      cairo_fill (cr);
      cairo_destroy (cr);

      gegl_buffer_linear_close (output, data);
      g_static_mutex_unlock (&mutex);
    }
  return  TRUE;
}
Ejemplo n.º 9
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties *o      = GEGL_PROPERTIES (operation);
  GeglRectangle in_rect = *gegl_buffer_get_extent (input);
  GeglRectangle out_rect = *gegl_buffer_get_extent (output);
  PixelDuster    *duster = pixel_duster_new (input, output, &in_rect, &out_rect,
                                             o->seek_distance,
                                             1,
                                             o->min_neigh,
                                             o->min_iter,
                                             o->chance_try,
                                             o->chance_retry,
                                             1.0,
                                             1.0,
                                             operation);
  seed_db (duster);
  gegl_buffer_copy (input, NULL, GEGL_ABYSS_NONE, output, NULL);
  fprintf (stderr, "adding transparent probes");
  pixel_duster_add_probes_for_transparent (duster);
  fprintf (stderr, "\n");
  pixel_duster_fill (duster);
  pixel_duster_destroy (duster);

  return TRUE;
}
Ejemplo n.º 10
0
static void
copy_one_component (GeglBuffer      *src,
                    GeglBuffer      *dst,
                    const gchar     *model,
                    const COMPONENT  component,
                    gboolean         clamp)
{
  const Babl *component_format, *dst_format;
  GeglBuffer *temp;
  const GeglRectangle *extent;

  /* We are working in linear double precison*/
  component_format = babl_format_new (babl_model (model),
                                      babl_type ("double"),
                                      babl_component (component.babl_name),
                                      NULL);

  /* We need to enforce linearity here
   * If the output is "Y'", the ouput of temp is already ok
   * If the output is "Y" , it will enforce gamma-decoding.
   * A bit tricky and suboptimal...
   */
  if (component.perceptual_channel)
    dst_format = babl_format ("Y' double");
  else
    dst_format = babl_format ("Y double");

  extent = gegl_buffer_get_extent (src);
  temp = gegl_buffer_new (extent, dst_format);

  /* we want to copy the component as is */
  gegl_buffer_set_format (temp, component_format);
  gegl_buffer_copy (src, NULL, temp, NULL);

  if (component.range_min != 0.0 || component.range_max != 1.0 || clamp)
    cpn_affine_transform_clamp (temp, component.range_min, component.range_max);

  /* This is our new "Y(') double" component buffer */
  gegl_buffer_set_format (temp, NULL);

  /* Now we let babl convert it back to the format that dst needs */
  gegl_buffer_copy (temp, NULL, dst, NULL);

  g_object_unref (temp);
}
Ejemplo n.º 11
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO          *o = GEGL_CHANT_PROPERTIES (operation);
  WarpPrivate         *priv = (WarpPrivate*) o->chant_data;
  gdouble              dist;
  gdouble              stamps;
  gdouble              spacing = MAX (o->size * 0.01, 0.5); /*1% spacing for starters*/

  GeglPathPoint        prev, next, lerp;
  gulong               i;
  GeglPathList        *event;

  priv->buffer = gegl_buffer_dup (input);

  event = gegl_path_get_path (o->stroke);

  prev = *(event->d.point);

  while (event->next)
    {
      event = event->next;
      next = *(event->d.point);
      dist = gegl_path_point_dist (&next, &prev);
      stamps = dist / spacing;

      if (stamps < 1)
        {
          stamp (o, result, next.x, next.y);
          prev = next;
        }
      else
        {
          for (i = 0; i < stamps; i++)
            {
              gegl_path_point_lerp (&lerp, &prev, &next, (i * spacing) / dist);
              stamp (o, result, lerp.x, lerp.y);
            }
          prev = lerp;
        }
    }

  /* Affect the output buffer */
  gegl_buffer_copy (priv->buffer, result, output, result);
  gegl_buffer_set_extent (output, gegl_buffer_get_extent (input));
  g_object_unref (priv->buffer);

  /* prepare for the recomputing of the op */
  priv->last_point_set = FALSE;

  return TRUE;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
TEST ()
{
    GeglBuffer    *buffer, *buffer2;
    GeglRectangle  bound = {0, 0, 20, 20};
    GeglRectangle  source = {15, 15, 10, 10};
    GeglRectangle  dest1 = {10, 10, 10, 10};
    GeglRectangle  dest2 = {0, 0, 10, 10};
    test_start ();
    buffer = gegl_buffer_new (&bound, babl_format ("Y float"));
    buffer2 = gegl_buffer_new (&bound, babl_format ("Y float"));

    vgrad (buffer);
    gegl_buffer_copy (buffer, &source, GEGL_ABYSS_NONE, buffer2, &dest1);
    gegl_buffer_copy (buffer, &source, GEGL_ABYSS_CLAMP, buffer2, &dest2);
    print_buffer (buffer2);
    g_object_unref (buffer);
    g_object_unref (buffer2);
    test_end ();
}
Ejemplo n.º 14
0
void
gegl_apply_op_valist (GeglBuffer  *buffer,
                      const gchar *first_property_name,
                      va_list      var_args)
{
    GeglBuffer  *tempbuf = NULL;
    GeglNode    *node;
    GeglNode    *source;
    GeglNode    *sink;

    g_return_if_fail (GEGL_IS_BUFFER (buffer));

    g_object_ref (buffer);

    source  = gegl_node_new_child (NULL, "operation", "gegl:buffer-source",
                                   "buffer", buffer,
                                   NULL);
    node   = gegl_node_new_child (NULL, "operation", first_property_name, NULL);

    if (!GEGL_IS_OPERATION_POINT_FILTER (node->operation))
    {
        tempbuf = gegl_buffer_new (gegl_buffer_get_extent (buffer), gegl_buffer_get_format (buffer));

        sink = gegl_node_new_child (NULL, "operation", "gegl:write-buffer",
                                    "buffer", tempbuf,
                                    NULL);
    }
    else
    {
        sink = gegl_node_new_child (NULL, "operation", "gegl:write-buffer",
                                    "buffer", buffer,
                                    NULL);
    }

    gegl_node_link_many (source, node, sink, NULL);

    gegl_node_set_props (node, var_args);

    gegl_node_process (sink);

    g_object_unref (source);
    g_object_unref (node);
    g_object_unref (sink);

    if (tempbuf)
    {
        gegl_buffer_copy (tempbuf, NULL, buffer, NULL);
        g_object_unref (tempbuf);
    }
    g_object_unref (buffer);
}
Ejemplo n.º 15
0
static gboolean
process (GeglOperation        *operation,
         GeglOperationContext *context,
         const gchar          *output_prop,
         const GeglRectangle  *roi,
         gint                  level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  GeglBuffer *input;
  GeglBuffer *output;

  if (! o->input_format || ! o->output_format)
    {
      g_warning ("cast-format: input-format or output-format are not set");
      return FALSE;
    }

  if (babl_format_get_bytes_per_pixel (o->input_format) !=
      babl_format_get_bytes_per_pixel (o->output_format))
    {
      g_warning ("cast-format: input-format and output-format have different bpp");
      return FALSE;
    }

  if (strcmp (output_prop, "output"))
    {
      g_warning ("cast-format: requested processing of %s pad", output_prop);
      return FALSE;
    }

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

  output = gegl_buffer_new (roi, o->input_format);

  gegl_buffer_copy (input,  roi, GEGL_ABYSS_NONE,
                    output, roi);
  gegl_buffer_set_format (output, o->output_format);

  g_object_unref (input);

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

  return TRUE;
}
Ejemplo n.º 16
0
static void
gimp_image_duplicate_mask (GimpImage *image,
                           GimpImage *new_image)
{
  GimpDrawable *mask;
  GimpDrawable *new_mask;

  mask     = GIMP_DRAWABLE (gimp_image_get_mask (image));
  new_mask = GIMP_DRAWABLE (gimp_image_get_mask (new_image));

  gegl_buffer_copy (gimp_drawable_get_buffer (mask), NULL,
                    gimp_drawable_get_buffer (new_mask), NULL);

  GIMP_CHANNEL (new_mask)->bounds_known   = FALSE;
  GIMP_CHANNEL (new_mask)->boundary_known = FALSE;
}
Ejemplo n.º 17
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         const GeglRectangle *result)
{
    GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

    if (o->buffer)
    {
        GeglBuffer *output = GEGL_BUFFER (o->buffer);

        gegl_buffer_copy (input, result, output, result);
    }

    return TRUE;
}
Ejemplo n.º 18
0
TEST ()
{
  GeglBuffer    *buffer, *buffer2;
  GeglRectangle  bound = {0, 0, 20, 20};
  GeglRectangle  source = {2, 2, 5, 5};
  GeglRectangle  dest = {10, 10, 5, 5};
  test_start ();
  buffer = gegl_buffer_new (&bound, babl_format ("Y float"));
  buffer2 = gegl_buffer_new (&bound, babl_format ("Y float"));

  vgrad (buffer);
  gegl_buffer_copy (buffer, &source, buffer2, &dest); 
  print_buffer (buffer2);
  gegl_buffer_destroy (buffer);
  gegl_buffer_destroy (buffer2);
  test_end ();
}
Ejemplo n.º 19
0
void
gimp_paint_core_cancel (GimpPaintCore *core,
                        GimpDrawable  *drawable)
{
  gint x, y;
  gint width, height;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));

  /*  Determine if any part of the image has been altered--
   *  if nothing has, then just return...
   */
  if ((core->x2 == core->x1) || (core->y2 == core->y1))
    return;

  if (gimp_rectangle_intersect (core->x1, core->y1,
                                core->x2 - core->x1,
                                core->y2 - core->y1,
                                0, 0,
                                gimp_item_get_width  (GIMP_ITEM (drawable)),
                                gimp_item_get_height (GIMP_ITEM (drawable)),
                                &x, &y, &width, &height))
    {
      gegl_buffer_copy (core->undo_buffer,
                        GEGL_RECTANGLE (x, y, width, height),
                        gimp_drawable_get_buffer (drawable),
                        GEGL_RECTANGLE (x, y, width, height));
    }

  g_object_unref (core->undo_buffer);
  core->undo_buffer = NULL;

  if (core->saved_proj_buffer)
    {
      g_object_unref (core->saved_proj_buffer);
      core->saved_proj_buffer = NULL;
    }

  gimp_drawable_update (drawable, x, y, width, height);

  gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
}
TEST ()
{
  GeglBuffer    *buffer, *buffer2;
  GeglRectangle  bound = {0, 0, 20, 20};
  test_start ();
  buffer = gegl_buffer_new (&bound, babl_format ("Y float"));
  vgrad (buffer);
  {
    GeglRectangle rect = *gegl_buffer_get_extent(buffer);

    rect.width-=10;
    rect.height-=10;
  buffer2 = gegl_buffer_new (gegl_buffer_get_extent (buffer), gegl_buffer_get_format (buffer));
  gegl_buffer_copy (buffer, &rect, buffer2, &rect);
  }
  print_buffer (buffer2);
  g_object_unref (buffer);
  g_object_unref (buffer2);
  test_end ();
}
Ejemplo n.º 21
0
GimpLayerMask *
gimp_layer_mask_new_from_buffer (GeglBuffer    *buffer,
                                 GimpImage     *image,
                                 const gchar   *name,
                                 const GimpRGB *color)
{
  GimpLayerMask  *layer_mask;
  GeglBuffer *dest;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  layer_mask = gimp_layer_mask_new (image,
                                    gegl_buffer_get_width  (buffer),
                                    gegl_buffer_get_height (buffer),
                                    name, color);

  dest = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer_mask));
  gegl_buffer_copy (buffer, NULL, dest, NULL);

  return layer_mask;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
void
gimp_paint_core_finish (GimpPaintCore *core,
                        GimpDrawable  *drawable,
                        gboolean       push_undo)
{
  GimpImage *image;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));

  if (core->applicator)
    {
      g_object_unref (core->applicator);
      core->applicator = NULL;
    }

  if (core->stroke_buffer)
    {
      g_array_free (core->stroke_buffer, TRUE);
      core->stroke_buffer = NULL;
    }

  if (core->mask_buffer)
    {
      g_object_unref (core->mask_buffer);
      core->mask_buffer = NULL;
    }

  if (core->comp_buffer)
    {
      g_object_unref (core->comp_buffer);
      core->comp_buffer = NULL;
    }

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  /*  Determine if any part of the image has been altered--
   *  if nothing has, then just return...
   */
  if ((core->x2 == core->x1) || (core->y2 == core->y1))
    {
      gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
      return;
    }

  if (push_undo)
    {
      GeglBuffer *buffer;
      gint        x, y, width, height;

      gimp_rectangle_intersect (core->x1, core->y1,
                                core->x2 - core->x1, core->y2 - core->y1,
                                0, 0,
                                gimp_item_get_width  (GIMP_ITEM (drawable)),
                                gimp_item_get_height (GIMP_ITEM (drawable)),
                                &x, &y, &width, &height);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT,
                                   core->undo_desc);

      GIMP_PAINT_CORE_GET_CLASS (core)->push_undo (core, image, NULL);

      buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
                                gimp_drawable_get_format (drawable));

      gegl_buffer_copy (core->undo_buffer,
                        GEGL_RECTANGLE (x, y, width, height),
                        buffer,
                        GEGL_RECTANGLE (0, 0, 0, 0));

      gimp_drawable_push_undo (drawable, NULL,
                               buffer, x, y, width, height);

      g_object_unref (buffer);

      gimp_image_undo_group_end (image);
    }

  g_object_unref (core->undo_buffer);
  core->undo_buffer = NULL;

  if (core->saved_proj_buffer)
    {
      g_object_unref (core->saved_proj_buffer);
      core->saved_proj_buffer = NULL;
    }

  gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
void
gimp_image_convert_precision (GimpImage     *image,
                              GimpPrecision  precision,
                              gint           layer_dither_type,
                              gint           text_layer_dither_type,
                              gint           mask_dither_type,
                              GimpProgress  *progress)
{
  GList       *all_drawables;
  GList       *list;
  const gchar *undo_desc = NULL;
  gint         nth_drawable, n_drawables;

  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (precision != gimp_image_get_precision (image));
  g_return_if_fail (precision == GIMP_PRECISION_U8_GAMMA ||
                    gimp_image_get_base_type (image) != GIMP_INDEXED);
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  all_drawables = g_list_concat (gimp_image_get_layer_list (image),
                                 gimp_image_get_channel_list (image));

  n_drawables = g_list_length (all_drawables) + 1 /* + selection */;

  switch (precision)
    {
    case GIMP_PRECISION_U8_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 8 bit linear integer");
      break;
    case GIMP_PRECISION_U8_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 8 bit gamma integer");
      break;
    case GIMP_PRECISION_U16_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 16 bit linear integer");
      break;
    case GIMP_PRECISION_U16_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma integer");
      break;
    case GIMP_PRECISION_U32_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 32 bit linear integer");
      break;
    case GIMP_PRECISION_U32_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma integer");
      break;
    case GIMP_PRECISION_HALF_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 16 bit linear floating point");
      break;
    case GIMP_PRECISION_HALF_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma floating point");
      break;
    case GIMP_PRECISION_FLOAT_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 32 bit linear floating point");
      break;
    case GIMP_PRECISION_FLOAT_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma floating point");
      break;
    case GIMP_PRECISION_DOUBLE_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 64 bit linear floating point");
      break;
    case GIMP_PRECISION_DOUBLE_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 64 bit gamma floating point");
      break;
    }

  if (progress)
    gimp_progress_start (progress, FALSE, "%s", undo_desc);

  g_object_freeze_notify (G_OBJECT (image));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               undo_desc);

  /*  Push the image precision to the stack  */
  gimp_image_undo_push_image_precision (image, NULL);

  /*  Set the new precision  */
  g_object_set (image, "precision", precision, NULL);

  for (list = all_drawables, nth_drawable = 0;
       list;
       list = g_list_next (list), nth_drawable++)
    {
      GimpDrawable *drawable = list->data;
      gint          dither_type;

      if (gimp_item_is_text_layer (GIMP_ITEM (drawable)))
        dither_type = text_layer_dither_type;
      else
        dither_type = layer_dither_type;

      gimp_drawable_convert_type (drawable, image,
                                  gimp_drawable_get_base_type (drawable),
                                  precision,
                                  dither_type,
                                  mask_dither_type,
                                  FALSE,
                                  TRUE);

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

  /*  convert the selection mask  */
  {
    GimpChannel *mask = gimp_image_get_mask (image);
    GeglBuffer  *buffer;

    gimp_image_undo_push_mask_precision (image, NULL, mask);

    buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                              gimp_image_get_width  (image),
                                              gimp_image_get_height (image)),
                              gimp_image_get_mask_format (image));

    gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), NULL,
                      GEGL_ABYSS_NONE,
                      buffer, NULL);

    gimp_drawable_set_buffer (GIMP_DRAWABLE (mask), FALSE, NULL, buffer);
    g_object_unref (buffer);

    nth_drawable++;

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

  gimp_image_undo_group_end (image);

  gimp_image_precision_changed (image);
  g_object_thaw_notify (G_OBJECT (image));

  if (progress)
    gimp_progress_end (progress);
}
Ejemplo n.º 26
0
GeglBuffer *
gimp_drawable_transform_buffer_flip (GimpDrawable        *drawable,
                                     GimpContext         *context,
                                     GeglBuffer          *orig_buffer,
                                     gint                 orig_offset_x,
                                     gint                 orig_offset_y,
                                     GimpOrientationType  flip_type,
                                     gdouble              axis,
                                     gboolean             clip_result,
                                     gint                *new_offset_x,
                                     gint                *new_offset_y)
{
  GeglBuffer    *new_buffer;
  GeglRectangle  src_rect;
  GeglRectangle  dest_rect;
  gint           orig_x, orig_y;
  gint           orig_width, orig_height;
  gint           new_x, new_y;
  gint           new_width, new_height;
  gint           i;

  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (GEGL_IS_BUFFER (orig_buffer), NULL);

  orig_x      = orig_offset_x;
  orig_y      = orig_offset_y;
  orig_width  = gegl_buffer_get_width (orig_buffer);
  orig_height = gegl_buffer_get_height (orig_buffer);

  new_x      = orig_x;
  new_y      = orig_y;
  new_width  = orig_width;
  new_height = orig_height;

  switch (flip_type)
    {
    case GIMP_ORIENTATION_HORIZONTAL:
      new_x = RINT (-((gdouble) orig_x +
                      (gdouble) orig_width - axis) + axis);
      break;

    case GIMP_ORIENTATION_VERTICAL:
      new_y = RINT (-((gdouble) orig_y +
                      (gdouble) orig_height - axis) + axis);
      break;

    case GIMP_ORIENTATION_UNKNOWN:
      g_return_val_if_reached (NULL);
      break;
    }

  new_buffer = gimp_gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                     new_width, new_height),
                                     gegl_buffer_get_format (orig_buffer));

  if (clip_result && (new_x != orig_x || new_y != orig_y))
    {
      GimpRGB    bg;
      GeglColor *color;
      gint       clip_x, clip_y;
      gint       clip_width, clip_height;

      *new_offset_x = orig_x;
      *new_offset_y = orig_y;

      /*  "Outside" a channel is transparency, not the bg color  */
      if (GIMP_IS_CHANNEL (drawable))
        gimp_rgba_set (&bg, 0.0, 0.0, 0.0, 0.0);
      else
        gimp_context_get_background (context, &bg);

      color = gimp_gegl_color_new (&bg);
      gegl_buffer_set_color (new_buffer, NULL, color);
      g_object_unref (color);

      if (gimp_rectangle_intersect (orig_x, orig_y, orig_width, orig_height,
                                    new_x, new_y, new_width, new_height,
                                    &clip_x, &clip_y,
                                    &clip_width, &clip_height))
        {
          orig_x = new_x = clip_x - orig_x;
          orig_y = new_y = clip_y - orig_y;
        }

      orig_width  = new_width  = clip_width;
      orig_height = new_height = clip_height;
    }
  else
    {
      *new_offset_x = new_x;
      *new_offset_y = new_y;

      orig_x = 0;
      orig_y = 0;
      new_x  = 0;
      new_y  = 0;
    }

  if (new_width == 0 && new_height == 0)
    return new_buffer;

  switch (flip_type)
    {
    case GIMP_ORIENTATION_HORIZONTAL:
      src_rect.x      = orig_x;
      src_rect.y      = orig_y;
      src_rect.width  = 1;
      src_rect.height = orig_height;

      dest_rect.x      = new_x + new_width - 1;
      dest_rect.y      = new_y;
      dest_rect.width  = 1;
      dest_rect.height = new_height;

      for (i = 0; i < orig_width; i++)
        {
          src_rect.x  = i + orig_x;
          dest_rect.x = new_x + new_width - i - 1;

          gegl_buffer_copy (orig_buffer, &src_rect,
                            new_buffer, &dest_rect);
        }
      break;

    case GIMP_ORIENTATION_VERTICAL:
      src_rect.x      = orig_x;
      src_rect.y      = orig_y;
      src_rect.width  = orig_width;
      src_rect.height = 1;

      dest_rect.x      = new_x;
      dest_rect.y      = new_y + new_height - 1;
      dest_rect.width  = new_width;
      dest_rect.height = 1;

      for (i = 0; i < orig_height; i++)
        {
          src_rect.y  = i + orig_y;
          dest_rect.y = new_y + new_height - i - 1;

          gegl_buffer_copy (orig_buffer, &src_rect,
                            new_buffer, &dest_rect);
        }
      break;

    case GIMP_ORIENTATION_UNKNOWN:
      break;
    }

  return new_buffer;
}
Ejemplo n.º 27
0
static void
gimp_brush_clipboard_buffer_changed (Gimp      *gimp,
                                     GimpBrush *brush)
{
  gint width;
  gint height;

  if (brush->mask)
    {
      gimp_temp_buf_unref (brush->mask);
      brush->mask = NULL;
    }

  if (brush->pixmap)
    {
      gimp_temp_buf_unref (brush->pixmap);
      brush->pixmap = NULL;
    }

  if (gimp->global_buffer)
    {
      GeglBuffer *buffer = gimp_buffer_get_buffer (gimp->global_buffer);
      const Babl *format = gegl_buffer_get_format (buffer);
      GeglBuffer *dest_buffer;

      width  = MIN (gimp_buffer_get_width  (gimp->global_buffer), 512);
      height = MIN (gimp_buffer_get_height (gimp->global_buffer), 512);

      brush->mask   = gimp_temp_buf_new (width, height,
                                         babl_format ("Y u8"));
      brush->pixmap = gimp_temp_buf_new (width, height,
                                         babl_format ("R'G'B' u8"));

      /*  copy the alpha channel into the brush's mask  */
      if (babl_format_has_alpha (format))
        {
          dest_buffer = gimp_temp_buf_create_buffer (brush->mask);

          gegl_buffer_set_format (dest_buffer, babl_format ("A u8"));
          gegl_buffer_copy (buffer, NULL, dest_buffer, NULL);

          g_object_unref (dest_buffer);
        }
      else
        {
          memset (gimp_temp_buf_get_data (brush->mask), 255,
                  width * height);
        }

      /*  copy the color channels into the brush's pixmap  */
      dest_buffer = gimp_temp_buf_create_buffer (brush->pixmap);

      gegl_buffer_copy (buffer, NULL, dest_buffer, NULL);

      g_object_unref (dest_buffer);
    }
  else
    {
      width  = 17;
      height = 17;

      brush->mask = gimp_temp_buf_new (width, height, babl_format ("Y u8"));
      gimp_temp_buf_data_clear (brush->mask);
    }

  brush->x_axis.x = width / 2;
  brush->x_axis.y = 0;
  brush->y_axis.x = 0;
  brush->y_axis.y = height / 2;

  gimp_data_dirty (GIMP_DATA (brush));
}
Ejemplo n.º 28
0
void
gimp_image_convert_precision (GimpImage     *image,
                              GimpPrecision  precision,
                              gint           layer_dither_type,
                              gint           text_layer_dither_type,
                              gint           mask_dither_type,
                              GimpProgress  *progress)
{
  GimpColorProfile *old_profile;
  GimpColorProfile *new_profile = NULL;
  const Babl       *old_format;
  const Babl       *new_format;
  GList            *all_drawables;
  GList            *list;
  const gchar      *undo_desc    = NULL;
  GimpProgress     *sub_progress = NULL;
  gint              nth_drawable, n_drawables;

  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (precision != gimp_image_get_precision (image));
  g_return_if_fail (precision == GIMP_PRECISION_U8_GAMMA ||
                    gimp_image_get_base_type (image) != GIMP_INDEXED);
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  all_drawables = g_list_concat (gimp_image_get_layer_list (image),
                                 gimp_image_get_channel_list (image));

  n_drawables = g_list_length (all_drawables) + 1 /* + selection */;

  if (progress)
    sub_progress = gimp_sub_progress_new (progress);

  switch (precision)
    {
    case GIMP_PRECISION_U8_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 8 bit linear integer");
      break;
    case GIMP_PRECISION_U8_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 8 bit gamma integer");
      break;
    case GIMP_PRECISION_U16_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 16 bit linear integer");
      break;
    case GIMP_PRECISION_U16_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma integer");
      break;
    case GIMP_PRECISION_U32_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 32 bit linear integer");
      break;
    case GIMP_PRECISION_U32_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma integer");
      break;
    case GIMP_PRECISION_HALF_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 16 bit linear floating point");
      break;
    case GIMP_PRECISION_HALF_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma floating point");
      break;
    case GIMP_PRECISION_FLOAT_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 32 bit linear floating point");
      break;
    case GIMP_PRECISION_FLOAT_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma floating point");
      break;
    case GIMP_PRECISION_DOUBLE_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 64 bit linear floating point");
      break;
    case GIMP_PRECISION_DOUBLE_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 64 bit gamma floating point");
      break;
    }

  if (progress)
    gimp_progress_start (progress, FALSE, "%s", undo_desc);

  g_object_freeze_notify (G_OBJECT (image));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               undo_desc);

  /*  Push the image precision to the stack  */
  gimp_image_undo_push_image_precision (image, NULL);

  old_profile = gimp_image_get_color_profile (image);
  old_format  = gimp_image_get_layer_format (image, FALSE);

  /*  Set the new precision  */
  g_object_set (image, "precision", precision, NULL);

  new_format = gimp_image_get_layer_format (image, FALSE);

  if (old_profile &&
      gimp_babl_format_get_linear (old_format) !=
      gimp_babl_format_get_linear (new_format))
    {
      GimpColorProfile *new_profile;

      /* when converting between linear and gamma, we create a new
       * profile using the original profile's chromacities and
       * whitepoint, but a linear/sRGB-gamma TRC.
       */

      if (gimp_babl_format_get_linear (new_format))
        {
          new_profile =
            gimp_color_profile_new_linear_from_color_profile (old_profile);
        }
      else
        {
          new_profile =
            gimp_color_profile_new_srgb_trc_from_color_profile (old_profile);
        }

      /* if a new profile cannot be be generated, convert to the
       * builtin profile, which is better than leaving the user with
       * broken colors
       */
      if (! new_profile)
        {
          new_profile = gimp_image_get_builtin_color_profile (image);
          g_object_ref (new_profile);
        }
    }

  for (list = all_drawables, nth_drawable = 0;
       list;
       list = g_list_next (list), nth_drawable++)
    {
      GimpDrawable *drawable = list->data;
      gint          dither_type;

      if (gimp_item_is_text_layer (GIMP_ITEM (drawable)))
        dither_type = text_layer_dither_type;
      else
        dither_type = layer_dither_type;

      if (sub_progress)
        gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                    nth_drawable, n_drawables);

      gimp_drawable_convert_type (drawable, image,
                                  gimp_drawable_get_base_type (drawable),
                                  precision,
                                  new_profile,
                                  dither_type,
                                  mask_dither_type,
                                  TRUE, sub_progress);
    }

  g_list_free (all_drawables);

  if (old_profile)
    {
      gimp_image_set_color_profile (image, new_profile, NULL);
      g_object_unref (new_profile);
    }

  /*  convert the selection mask  */
  {
    GimpChannel *mask = gimp_image_get_mask (image);
    GeglBuffer  *buffer;

    if (sub_progress)
      gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                  nth_drawable, n_drawables);

    gimp_image_undo_push_mask_precision (image, NULL, mask);

    buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                              gimp_image_get_width  (image),
                                              gimp_image_get_height (image)),
                              gimp_image_get_mask_format (image));

    gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), NULL,
                      GEGL_ABYSS_NONE,
                      buffer, NULL);

    gimp_drawable_set_buffer (GIMP_DRAWABLE (mask), FALSE, NULL, buffer);
    g_object_unref (buffer);

    nth_drawable++;
  }

  if (sub_progress)
    gimp_progress_set_value (sub_progress, 1.0);

  gimp_image_undo_group_end (image);

  gimp_image_precision_changed (image);
  g_object_thaw_notify (G_OBJECT (image));

  if (sub_progress)
    g_object_unref (sub_progress);

  if (progress)
    gimp_progress_end (progress);
}
Ejemplo n.º 29
0
static gboolean
gimp_smudge_start (GimpPaintCore    *paint_core,
                   GimpDrawable     *drawable,
                   GimpPaintOptions *paint_options,
                   const GimpCoords *coords)
{
  GimpSmudge *smudge = GIMP_SMUDGE (paint_core);
  GeglBuffer *paint_buffer;
  gint        paint_buffer_x;
  gint        paint_buffer_y;
  gint        accum_size;
  gint        x, y;

  paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable,
                                                   paint_options, coords,
                                                   &paint_buffer_x,
                                                   &paint_buffer_y);
  if (! paint_buffer)
    return FALSE;

  gimp_smudge_accumulator_size (paint_options, coords, &accum_size);

  /*  Allocate the accumulation buffer */
  smudge->accum_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                          accum_size,
                                                          accum_size),
                                          babl_format ("RGBA float"));

  /*  adjust the x and y coordinates to the upper left corner of the
   *  accumulator
   */
  gimp_smudge_accumulator_coords (paint_core, coords, &x, &y);

  /*  If clipped, prefill the smudge buffer with the color at the
   *  brush position.
   */
  if (x != paint_buffer_x ||
      y != paint_buffer_y ||
      accum_size != gegl_buffer_get_width  (paint_buffer) ||
      accum_size != gegl_buffer_get_height (paint_buffer))
    {
      GimpRGB    pixel;
      GeglColor *color;

      gimp_pickable_get_color_at (GIMP_PICKABLE (drawable),
                                  CLAMP ((gint) coords->x,
                                         0,
                                         gimp_item_get_width (GIMP_ITEM (drawable)) - 1),
                                  CLAMP ((gint) coords->y,
                                         0,
                                         gimp_item_get_height (GIMP_ITEM (drawable)) - 1),
                                  &pixel);

      color = gimp_gegl_color_new (&pixel);
      gegl_buffer_set_color (smudge->accum_buffer, NULL, color);
      g_object_unref (color);
    }

  /* copy the region under the original painthit. */
  gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
                    GEGL_RECTANGLE (paint_buffer_x,
                                    paint_buffer_y,
                                    gegl_buffer_get_width  (paint_buffer),
                                    gegl_buffer_get_height (paint_buffer)),
                    smudge->accum_buffer,
                    GEGL_RECTANGLE (paint_buffer_x - x,
                                    paint_buffer_y - y,
                                    0, 0));

  return TRUE;
}
Ejemplo n.º 30
0
static void
gimp_smudge_motion (GimpPaintCore    *paint_core,
                    GimpDrawable     *drawable,
                    GimpPaintOptions *paint_options,
                    const GimpCoords *coords)
{
  GimpSmudge         *smudge   = GIMP_SMUDGE (paint_core);
  GimpSmudgeOptions  *options  = GIMP_SMUDGE_OPTIONS (paint_options);
  GimpContext        *context  = GIMP_CONTEXT (paint_options);
  GimpDynamics       *dynamics = GIMP_BRUSH_CORE (paint_core)->dynamics;
  GimpImage          *image    = gimp_item_get_image (GIMP_ITEM (drawable));
  GeglBuffer         *paint_buffer;
  gint                paint_buffer_x;
  gint                paint_buffer_y;
  gint                paint_buffer_width;
  gint                paint_buffer_height;
  gdouble             fade_point;
  gdouble             opacity;
  gdouble             rate;
  gdouble             dynamic_rate;
  gint                x, y;
  gdouble             force;
  gdouble             dyn_force;
  GimpDynamicsOutput *dyn_output = NULL;

  fade_point = gimp_paint_options_get_fade (paint_options, image,
                                            paint_core->pixel_dist);

  opacity = gimp_dynamics_get_linear_value (dynamics,
                                            GIMP_DYNAMICS_OUTPUT_OPACITY,
                                            coords,
                                            paint_options,
                                            fade_point);
  if (opacity == 0.0)
    return;

  paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable,
                                                   paint_options, coords,
                                                   &paint_buffer_x,
                                                   &paint_buffer_y);
  if (! paint_buffer)
    return;

  paint_buffer_width  = gegl_buffer_get_width  (paint_buffer);
  paint_buffer_height = gegl_buffer_get_height (paint_buffer);

  /*  Get the unclipped acumulator coordinates  */
  gimp_smudge_accumulator_coords (paint_core, coords, &x, &y);

  /* Enable dynamic rate */
  dynamic_rate = gimp_dynamics_get_linear_value (dynamics,
                                                 GIMP_DYNAMICS_OUTPUT_RATE,
                                                 coords,
                                                 paint_options,
                                                 fade_point);

  rate = (options->rate / 100.0) * dynamic_rate;

  /*  Smudge uses the buffer Accum.
   *  For each successive painthit Accum is built like this
   *    Accum =  rate*Accum  + (1-rate)*I.
   *  where I is the pixels under the current painthit.
   *  Then the paint area (paint_area) is built as
   *    (Accum,1) (if no alpha),
   */

  gimp_gegl_smudge_blend (smudge->accum_buffer,
                          GEGL_RECTANGLE (paint_buffer_x - x,
                                          paint_buffer_y - y,
                                          paint_buffer_width,
                                          paint_buffer_height),
                          gimp_drawable_get_buffer (drawable),
                          GEGL_RECTANGLE (paint_buffer_x,
                                          paint_buffer_y,
                                          paint_buffer_width,
                                          paint_buffer_height),
                          smudge->accum_buffer,
                          GEGL_RECTANGLE (paint_buffer_x - x,
                                          paint_buffer_y - y,
                                          paint_buffer_width,
                                          paint_buffer_height),
                          rate);

  gegl_buffer_copy (smudge->accum_buffer,
                    GEGL_RECTANGLE (paint_buffer_x - x,
                                    paint_buffer_y - y,
                                    paint_buffer_width,
                                    paint_buffer_height),
                    paint_buffer,
                    GEGL_RECTANGLE (0, 0, 0, 0));

  dyn_output = gimp_dynamics_get_output (dynamics,
                                         GIMP_DYNAMICS_OUTPUT_FORCE);

  dyn_force = gimp_dynamics_get_linear_value (dynamics,
                                              GIMP_DYNAMICS_OUTPUT_FORCE,
                                              coords,
                                              paint_options,
                                              fade_point);

  if (gimp_dynamics_output_is_enabled (dyn_output))
    force = dyn_force;
  else
    force = paint_options->brush_force;

  gimp_brush_core_replace_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
                                  coords,
                                  MIN (opacity, GIMP_OPACITY_OPAQUE),
                                  gimp_context_get_opacity (context),
                                  gimp_paint_options_get_brush_mode (paint_options),
                                  force,
                                  GIMP_PAINT_INCREMENTAL);
}