app: in GimpSourceCore's vfuncs, pass GeglBuffers around not PixelRegions

which simplifies a lot of code, just don't look at GimpHeal until
it's completely ported ;)
This commit is contained in:
Michael Natterer 2012-03-30 22:11:46 +02:00
parent 1cee8d79bf
commit 95bf75d7a5
6 changed files with 181 additions and 233 deletions

View file

@ -60,7 +60,7 @@ static void gimp_clone_motion (GimpSourceCore *source_core,
const GimpCoords *coords,
gdouble opacity,
GimpPickable *src_pickable,
PixelRegion *srcPR,
GeglBuffer *src_buffer,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
@ -148,7 +148,7 @@ gimp_clone_motion (GimpSourceCore *source_core,
const GimpCoords *coords,
gdouble opacity,
GimpPickable *src_pickable,
PixelRegion *srcPR,
GeglBuffer *src_buffer,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
@ -170,33 +170,24 @@ gimp_clone_motion (GimpSourceCore *source_core,
{
case GIMP_IMAGE_CLONE:
{
const Babl *fish;
PixelRegion destPR;
gpointer pr;
GeglBuffer *dest_buffer;
fish = babl_fish (gimp_pickable_get_format_with_alpha (src_pickable),
gimp_drawable_get_format_with_alpha (drawable));
dest_buffer =
gegl_buffer_linear_new_from_data (temp_buf_get_data (paint_area),
gimp_drawable_get_format_with_alpha (drawable),
GIMP_GEGL_RECT (paint_area_offset_x, paint_area_offset_y,
paint_area_width, paint_area_height),
paint_area->width *
paint_area->bytes,
NULL, NULL);
pixel_region_init_temp_buf (&destPR, paint_area,
paint_area_offset_x, paint_area_offset_y,
paint_area_width, paint_area_height);
gegl_buffer_copy (src_buffer,
GIMP_GEGL_RECT (0, 0,
paint_area_width, paint_area_height),
dest_buffer,
NULL);
pr = pixel_regions_register (2, srcPR, &destPR);
for (; pr != NULL; pr = pixel_regions_process (pr))
{
guchar *s = srcPR->data;
guchar *d = destPR.data;
gint y;
for (y = 0; y < destPR.h; y++)
{
babl_process (fish, s, d, destPR.w);
s += srcPR->rowstride;
d += destPR.rowstride;
}
}
g_object_unref (dest_buffer);
}
break;

View file

@ -31,6 +31,8 @@
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "gegl/gimp-gegl-utils.h"
#include "core/gimpbrush.h"
#include "core/gimpdrawable.h"
#include "core/gimpdynamics.h"
@ -102,7 +104,7 @@ static void gimp_heal_motion (GimpSourceCore *source_core,
const GimpCoords *coords,
gdouble opacity,
GimpPickable *src_pickable,
PixelRegion *srcPR,
GeglBuffer *src_buffer,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
@ -440,7 +442,7 @@ gimp_heal_motion (GimpSourceCore *source_core,
const GimpCoords *coords,
gdouble opacity,
GimpPickable *src_pickable,
PixelRegion *srcPR,
GeglBuffer *src_buffer,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
@ -454,13 +456,10 @@ gimp_heal_motion (GimpSourceCore *source_core,
GimpDynamics *dynamics = GIMP_BRUSH_CORE (paint_core)->dynamics;
GimpDynamicsOutput *hardness_output;
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
TempBuf *src;
TempBuf *temp;
PixelRegion origPR;
PixelRegion tempPR;
TempBuf *src_temp_buf;
TempBuf *dest_temp_buf;
PixelRegion srcPR;
PixelRegion destPR;
const Babl *format;
const Babl *format_alpha;
const TempBuf *mask_buf;
gdouble fade_point;
gdouble hardness;
@ -481,106 +480,89 @@ gimp_heal_motion (GimpSourceCore *source_core,
GIMP_BRUSH_HARD,
hardness);
format = gimp_pickable_get_format (src_pickable);
format_alpha = gimp_pickable_get_format_with_alpha (src_pickable);
/* copy the source buffer because we are going to modify it */
{
GeglBuffer *tmp;
/* we need the source area with alpha and we modify it, so make a copy */
src = temp_buf_new (srcPR->w, srcPR->h,
babl_format_get_bytes_per_pixel (format_alpha),
0, 0, NULL);
src_temp_buf = temp_buf_new (gegl_buffer_get_width (src_buffer),
gegl_buffer_get_height (src_buffer),
gimp_drawable_bytes_with_alpha (drawable),
0, 0, NULL);
pixel_region_init_temp_buf (&tempPR, src, 0, 0, src->width, src->height);
tmp =
gegl_buffer_linear_new_from_data (temp_buf_get_data (src_temp_buf),
gimp_drawable_get_format_with_alpha (drawable),
GIMP_GEGL_RECT (0, 0,
src_temp_buf->width,
src_temp_buf->height),
src_temp_buf->width *
src_temp_buf->bytes,
NULL, NULL);
/*
* the effect of the following is to copy the contents of the source
* region to the "src" temp-buf, adding an alpha channel if necessary
*/
if (babl_format_has_alpha (format))
copy_region (srcPR, &tempPR);
else
add_alpha_region (srcPR, &tempPR);
gegl_buffer_copy (src_buffer, NULL, tmp, NULL);
g_object_unref (tmp);
}
/* reinitialize srcPR */
pixel_region_init_temp_buf (srcPR, src, 0, 0, src->width, src->height);
{
GeglBuffer *tmp;
if (format_alpha != gimp_drawable_get_format_with_alpha (drawable))
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
TempBuf *temp2;
gboolean new_buf;
dest_temp_buf = temp_buf_new (paint_area->width,
paint_area->height,
gimp_drawable_bytes_with_alpha (drawable),
0, 0, NULL);
temp2 = gimp_image_transform_temp_buf (image,
gimp_drawable_type_with_alpha (drawable),
src, &new_buf);
tmp =
gegl_buffer_linear_new_from_data (temp_buf_get_data (dest_temp_buf),
gimp_drawable_get_format_with_alpha (drawable),
GIMP_GEGL_RECT (0, 0,
dest_temp_buf->width,
dest_temp_buf->height),
dest_temp_buf->width *
dest_temp_buf->bytes,
NULL, NULL);
if (new_buf)
temp_buf_free (src);
gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
GIMP_GEGL_RECT (paint_area->x, paint_area->y,
paint_area->width, paint_area->height),
tmp,
GIMP_GEGL_RECT (0, 0, 0, 0));
g_object_unref (tmp);
}
src = temp2;
}
/* reinitialize srcPR */
pixel_region_init_temp_buf (srcPR, src, 0, 0, src->width, src->height);
/* FIXME: the area under the cursor and the source area should be x% larger
* than the brush size. Otherwise the brush must be a lot bigger than the
* area to heal to get good results. Having the user pick such a large brush
* is perhaps counter-intutitive?
*/
pixel_region_init (&origPR, gimp_drawable_get_tiles (drawable),
paint_area->x, paint_area->y,
paint_area->width, paint_area->height, FALSE);
temp = temp_buf_new (origPR.w, origPR.h,
gimp_drawable_bytes_with_alpha (drawable),
0, 0, NULL);
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, temp->width, temp->height);
if (gimp_drawable_has_alpha (drawable))
copy_region (&origPR, &tempPR);
else
add_alpha_region (&origPR, &tempPR);
/* reinitialize tempPR */
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, temp->width, temp->height);
/* now tempPR holds the data under the cursor and
* srcPR holds the area to sample from
*/
/* get the destination to paint to */
pixel_region_init_temp_buf (&destPR, paint_area,
paint_area_offset_x, paint_area_offset_y,
paint_area_width, paint_area_height);
/* check that srcPR, tempPR and destPR are the same size and tempPR is inside of layer */
if ((srcPR->w != tempPR.w) || (srcPR->w != destPR.w) ||
(srcPR->h != tempPR.h) || (srcPR->h != destPR.h) ||
(tempPR.w <= 0) ||
(tempPR.h <= 0))
/* check that srcPR, tempPR, destPR, and mask_buf are the same size */
if (src_temp_buf->width != dest_temp_buf->width ||
src_temp_buf->height != dest_temp_buf->height)
{
/* this generally means that the source point has hit the edge of the
layer, so it is not an error and we should not complain, just
don't do anything */
temp_buf_free (src);
temp_buf_free (temp);
temp_buf_free (src_temp_buf);
temp_buf_free (dest_temp_buf);
return;
}
/* heal tempPR using srcPR */
gimp_heal_region (&tempPR, srcPR, mask_buf);
pixel_region_init_temp_buf (&srcPR, src_temp_buf,
0, 0,
mask_buf->width, mask_buf->height);
pixel_region_init_temp_buf (&destPR, dest_temp_buf,
0, 0,
mask_buf->width, mask_buf->height);
temp_buf_free (src);
/* heal destPR using srcPR */
gimp_heal_region (&destPR, &srcPR, mask_buf);
/* reinitialize tempPR */
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, temp->width, temp->height);
pixel_region_init_temp_buf (&srcPR, dest_temp_buf,
0, 0,
mask_buf->width, mask_buf->height);
pixel_region_init_temp_buf (&destPR, paint_area,
paint_area_offset_x,
paint_area_offset_y,
paint_area_width,
paint_area_height);
copy_region (&tempPR, &destPR);
temp_buf_free (temp);
copy_region (&srcPR, &destPR);
/* replace the canvas with our healed data */
gimp_brush_core_replace_canvas (GIMP_BRUSH_CORE (paint_core), drawable,

View file

@ -46,35 +46,32 @@
#include "gimp-intl.h"
static void gimp_perspective_clone_finalize (GObject *object);
static gboolean gimp_perspective_clone_start (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
GError **error);
static void gimp_perspective_clone_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
GimpPaintState paint_state,
guint32 time);
static gboolean gimp_perspective_clone_start (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
GError **error);
static void gimp_perspective_clone_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
GimpPaintState paint_state,
guint32 time);
static GeglBuffer * gimp_perspective_clone_get_source (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPickable *src_pickable,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height);
static gboolean gimp_perspective_clone_get_source (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPickable *src_pickable,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height,
PixelRegion *srcPR);
static void gimp_perspective_clone_get_matrix (GimpPerspectiveClone *clone,
GimpMatrix3 *matrix);
static void gimp_perspective_clone_get_matrix (GimpPerspectiveClone *clone,
GimpMatrix3 *matrix);
G_DEFINE_TYPE (GimpPerspectiveClone, gimp_perspective_clone,
@ -98,12 +95,9 @@ gimp_perspective_clone_register (Gimp *gimp,
static void
gimp_perspective_clone_class_init (GimpPerspectiveCloneClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
GimpSourceCoreClass *source_core_class = GIMP_SOURCE_CORE_CLASS (klass);
object_class->finalize = gimp_perspective_clone_finalize;
paint_core_class->start = gimp_perspective_clone_start;
paint_core_class->paint = gimp_perspective_clone_paint;
@ -123,20 +117,6 @@ gimp_perspective_clone_init (GimpPerspectiveClone *clone)
gimp_matrix3_identity (&clone->transform_inv);
}
static void
gimp_perspective_clone_finalize (GObject *object)
{
GimpPerspectiveClone *clone = GIMP_PERSPECTIVE_CLONE (object);
if (clone->src_area)
{
temp_buf_free (clone->src_area);
clone->src_area = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
gimp_perspective_clone_start (GimpPaintCore *paint_core,
GimpDrawable *drawable,
@ -271,7 +251,7 @@ gimp_perspective_clone_paint (GimpPaintCore *paint_core,
g_object_notify (G_OBJECT (clone), "src-y");
}
static gboolean
static GeglBuffer *
gimp_perspective_clone_get_source (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
@ -282,8 +262,7 @@ gimp_perspective_clone_get_source (GimpSourceCore *source_core,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height,
PixelRegion *srcPR)
gint *paint_area_height)
{
GimpPerspectiveClone *clone = GIMP_PERSPECTIVE_CLONE (source_core);
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
@ -394,19 +373,8 @@ gimp_perspective_clone_get_source (GimpSourceCore *source_core,
g_object_unref (temp_buffer);
}
clone->src_area = temp_buf_resize (clone->src_area,
babl_format_get_bytes_per_pixel (src_format_alpha),
0, 0,
x2d - x1d, y2d - y1d);
dest_buffer =
gegl_buffer_linear_new_from_data (temp_buf_get_data (clone->src_area),
gimp_bpp_to_babl_format (clone->src_area->bytes),
GIMP_GEGL_RECT (0, 0,
clone->src_area->width,
clone->src_area->height),
clone->src_area->width * clone->src_area->bytes,
NULL, NULL);
dest_buffer = gegl_buffer_new (GIMP_GEGL_RECT (0, 0, x2d - x1d, y2d - y1d),
src_format_alpha);
gimp_perspective_clone_get_matrix (clone, &matrix);
@ -431,12 +399,8 @@ gimp_perspective_clone_get_source (GimpSourceCore *source_core,
g_object_unref (affine);
g_object_unref (orig_buffer);
g_object_unref (dest_buffer);
pixel_region_init_temp_buf (srcPR, clone->src_area,
0, 0, x2d - x1d, y2d - y1d);
return TRUE;
return dest_buffer;
}

View file

@ -44,8 +44,6 @@ struct _GimpPerspectiveClone
GimpMatrix3 transform;
GimpMatrix3 transform_inv;
TempBuf *src_area;
};
struct _GimpPerspectiveCloneClass

View file

@ -27,6 +27,8 @@
#include "base/tile-manager.h"
#include "base/pixel-region.h"
#include "gegl/gimp-gegl-utils.h"
#include "core/gimp.h"
#include "core/gimpdrawable.h"
#include "core/gimpdynamics.h"
@ -78,7 +80,8 @@ static void gimp_source_core_motion (GimpSourceCore *source_core,
const GimpCoords *coords);
#endif
static gboolean gimp_source_core_real_get_source (GimpSourceCore *source_core,
static GeglBuffer *
gimp_source_core_real_get_source (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPickable *src_pickable,
@ -88,8 +91,7 @@ static gboolean gimp_source_core_real_get_source (GimpSourceCore *source_core,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height,
PixelRegion *srcPR);
gint *paint_area_height);
static void gimp_source_core_set_src_drawable (GimpSourceCore *source_core,
GimpDrawable *drawable);
@ -351,7 +353,7 @@ gimp_source_core_motion (GimpSourceCore *source_core,
GimpDynamicsOutput *opacity_output;
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GimpPickable *src_pickable = NULL;
PixelRegion srcPR;
GeglBuffer *src_buffer = NULL;
gint src_offset_x;
gint src_offset_y;
TempBuf *paint_area;
@ -409,8 +411,10 @@ gimp_source_core_motion (GimpSourceCore *source_core,
paint_area_width = paint_area->width;
paint_area_height = paint_area->height;
if (options->use_source &&
! GIMP_SOURCE_CORE_GET_CLASS (source_core)->get_source (source_core,
if (options->use_source)
{
src_buffer =
GIMP_SOURCE_CORE_GET_CLASS (source_core)->get_source (source_core,
drawable,
paint_options,
src_pickable,
@ -420,10 +424,9 @@ gimp_source_core_motion (GimpSourceCore *source_core,
&paint_area_offset_x,
&paint_area_offset_y,
&paint_area_width,
&paint_area_height,
&srcPR))
{
return;
&paint_area_height);
if (! src_buffer)
return;
}
/* Set the paint area to transparent */
@ -435,7 +438,7 @@ gimp_source_core_motion (GimpSourceCore *source_core,
coords,
opacity,
src_pickable,
&srcPR,
src_buffer,
src_offset_x,
src_offset_y,
paint_area,
@ -443,9 +446,12 @@ gimp_source_core_motion (GimpSourceCore *source_core,
paint_area_offset_y,
paint_area_width,
paint_area_height);
if (src_buffer)
g_object_unref (src_buffer);
}
static gboolean
static GeglBuffer *
gimp_source_core_real_get_source (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
@ -456,13 +462,13 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height,
PixelRegion *srcPR)
gint *paint_area_height)
{
GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GimpImage *src_image = gimp_pickable_get_image (src_pickable);
TileManager *src_tiles = gimp_pickable_get_tiles (src_pickable);
GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GimpImage *src_image = gimp_pickable_get_image (src_pickable);
GeglBuffer *src_buffer = gimp_pickable_get_buffer (src_pickable);
GeglBuffer *dest_buffer;
gint x, y;
gint width, height;
@ -471,8 +477,8 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
paint_area->width,
paint_area->height,
0, 0,
tile_manager_width (src_tiles),
tile_manager_height (src_tiles),
gegl_buffer_get_width (src_buffer),
gegl_buffer_get_height (src_buffer),
&x, &y,
&width, &height))
{
@ -488,9 +494,13 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
if (( options->sample_merged && (src_image != image)) ||
(! options->sample_merged && (source_core->src_drawable != drawable)))
{
pixel_region_init (srcPR, src_tiles,
x, y, width, height,
FALSE);
dest_buffer = gegl_buffer_new (GIMP_GEGL_RECT (0, 0, width, height),
gimp_pickable_get_format (src_pickable));
gegl_buffer_copy (src_buffer,
GIMP_GEGL_RECT (x, y, width, height),
dest_buffer,
GIMP_GEGL_RECT (0, 0, 0, 0));
}
else
{
@ -506,8 +516,12 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
GIMP_DRAWABLE (src_pickable),
x, y, width, height);
pixel_region_init_temp_buf (srcPR, orig,
0, 0, width, height);
dest_buffer =
gegl_buffer_linear_new_from_data (temp_buf_get_data (orig),
gimp_pickable_get_format (src_pickable),
GIMP_GEGL_RECT (0, 0, width, height),
orig->width * orig->bytes,
NULL, NULL);
}
*paint_area_offset_x = x - (paint_area->x + src_offset_x);
@ -515,7 +529,7 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
*paint_area_width = width;
*paint_area_height = height;
return TRUE;
return dest_buffer;
}
static void

View file

@ -54,33 +54,32 @@ struct _GimpSourceCoreClass
{
GimpBrushCoreClass parent_class;
gboolean (* get_source) (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPickable *src_pickable,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height,
PixelRegion *srcPR);
GeglBuffer * (* get_source) (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPickable *src_pickable,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
gint *paint_area_offset_x,
gint *paint_area_offset_y,
gint *paint_area_width,
gint *paint_area_height);
void (* motion) (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
gdouble opacity,
GimpPickable *src_pickable,
PixelRegion *srcPR,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
gint paint_area_offset_x,
gint paint_area_offset_y,
gint paint_area_width,
gint paint_area_height);
void (* motion) (GimpSourceCore *source_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
gdouble opacity,
GimpPickable *src_pickable,
GeglBuffer *src_buffer,
gint src_offset_x,
gint src_offset_y,
TempBuf *paint_area,
gint paint_area_offset_x,
gint paint_area_offset_y,
gint paint_area_width,
gint paint_area_height);
};