mirror of https://github.com/GNOME/gimp.git
Bill Skaggs <weskaggs@primate.ucdavis.edu>
* app/paint/gimpheal.c: heal from edge of brush mask instead of edges of paint area. * app/paint/gimpbrushcore.[ch]: export gimp_brush_core_get_brush_mask() to enable use of mask. svn path=/trunk/; revision=24324
This commit is contained in:
parent
8f674d6dda
commit
a708a16c29
|
@ -1,3 +1,11 @@
|
|||
2007-12-11 Bill Skaggs <weskaggs@primate.ucdavis.edu>
|
||||
|
||||
* app/paint/gimpheal.c: heal from edge of brush mask
|
||||
instead of edges of paint area.
|
||||
|
||||
* app/paint/gimpbrushcore.[ch]: export
|
||||
gimp_brush_core_get_brush_mask() to enable use of mask.
|
||||
|
||||
2007-12-11 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/pdb/Makefile.am
|
||||
|
|
|
@ -106,8 +106,6 @@ static TempBuf * gimp_brush_core_scale_mask (GimpBrushCore *core,
|
|||
static TempBuf * gimp_brush_core_scale_pixmap (GimpBrushCore *core,
|
||||
GimpBrush *brush);
|
||||
|
||||
static TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore *core,
|
||||
GimpBrushApplicationMode brush_hardness);
|
||||
static void gimp_brush_core_invalidate_cache (GimpBrush *brush,
|
||||
GimpBrushCore *core);
|
||||
|
||||
|
@ -1344,7 +1342,7 @@ gimp_brush_core_scale_pixmap (GimpBrushCore *core,
|
|||
return core->scale_pixmap;
|
||||
}
|
||||
|
||||
static TempBuf *
|
||||
TempBuf *
|
||||
gimp_brush_core_get_brush_mask (GimpBrushCore *core,
|
||||
GimpBrushApplicationMode brush_hardness)
|
||||
{
|
||||
|
|
|
@ -121,10 +121,12 @@ void gimp_brush_core_replace_canvas (GimpBrushCore *core,
|
|||
GimpPaintApplicationMode mode);
|
||||
|
||||
void gimp_brush_core_color_area_with_pixmap
|
||||
(GimpBrushCore *core,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
GimpBrushApplicationMode mode);
|
||||
(GimpBrushCore *core,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
GimpBrushApplicationMode mode);
|
||||
|
||||
TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore *core,
|
||||
GimpBrushApplicationMode brush_hardness);
|
||||
|
||||
#endif /* __GIMP_BRUSH_CORE_H__ */
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "core/gimppickable.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpdrawable.h"
|
||||
#include "core/gimpbrush.h"
|
||||
|
||||
#include "gimpheal.h"
|
||||
#include "gimpsourceoptions.h"
|
||||
|
@ -50,25 +51,60 @@
|
|||
*/
|
||||
|
||||
|
||||
static gboolean gimp_heal_start (GimpPaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options,
|
||||
GimpCoords *coords,
|
||||
GError **error);
|
||||
static gboolean gimp_heal_start (GimpPaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options,
|
||||
GimpCoords *coords,
|
||||
GError **error);
|
||||
|
||||
static void gimp_heal_class_init (GimpHealClass *klass);
|
||||
|
||||
static void gimp_heal_init (GimpHeal *heal);
|
||||
|
||||
static void gimp_heal_substitute_0_for_1 (PixelRegion *pr);
|
||||
|
||||
static void gimp_heal_divide (PixelRegion *topPR,
|
||||
PixelRegion *bottomPR,
|
||||
gdouble *result);
|
||||
|
||||
static void gimp_heal_multiply (gdouble *first,
|
||||
PixelRegion *secondPR,
|
||||
PixelRegion *resultPR);
|
||||
|
||||
static gdouble gimp_heal_laplace_iteration (gdouble *matrix,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
guchar *mask);
|
||||
|
||||
static void gimp_heal_laplace_loop (gdouble *matrix,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution,
|
||||
guchar *mask);
|
||||
|
||||
static PixelRegion *gimp_heal_region (PixelRegion *tempPR,
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *mask_buf);
|
||||
|
||||
static void gimp_heal_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options,
|
||||
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);
|
||||
|
||||
|
||||
|
||||
static void gimp_heal_motion (GimpSourceCore *source_core,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintOptions *paint_options,
|
||||
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);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpHeal, gimp_heal, GIMP_TYPE_SOURCE_CORE)
|
||||
|
@ -268,7 +304,8 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
|||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution)
|
||||
gdouble *solution,
|
||||
guchar *mask)
|
||||
{
|
||||
gint rowstride = width * depth;
|
||||
gint i, j, k;
|
||||
|
@ -279,10 +316,10 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
|||
{
|
||||
for (j = 0; j < width; j++)
|
||||
{
|
||||
if ((i == 0) || (i == (height - 1)) ||
|
||||
if ((0 == *mask) || (i == 0) || (i == (height - 1)) ||
|
||||
(j == 0) || (j == (height - 1)))
|
||||
{
|
||||
/* do nothing at the boundary */
|
||||
/* do nothing at the boundary or outside mask */
|
||||
for (k = 0; k < depth; k++)
|
||||
*(solution + k) = *(matrix + k);
|
||||
}
|
||||
|
@ -308,6 +345,7 @@ gimp_heal_laplace_iteration (gdouble *matrix,
|
|||
/* advance pointers to data */
|
||||
matrix += depth;
|
||||
solution += depth;
|
||||
mask++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,7 +360,8 @@ gimp_heal_laplace_loop (gdouble *matrix,
|
|||
gint height,
|
||||
gint depth,
|
||||
gint width,
|
||||
gdouble *solution)
|
||||
gdouble *solution,
|
||||
guchar *mask)
|
||||
{
|
||||
#define EPSILON 0.0001
|
||||
#define MAX_ITER 500
|
||||
|
@ -334,8 +373,8 @@ gimp_heal_laplace_loop (gdouble *matrix,
|
|||
gdouble sqr_err;
|
||||
|
||||
/* do one iteration and store the amount of error */
|
||||
sqr_err = gimp_heal_laplace_iteration (matrix,
|
||||
height, depth, width, solution);
|
||||
sqr_err = gimp_heal_laplace_iteration (matrix, height, depth, width,
|
||||
solution, mask);
|
||||
|
||||
/* copy solution to matrix */
|
||||
memcpy (matrix, solution, width * height * depth * sizeof (double));
|
||||
|
@ -353,10 +392,12 @@ gimp_heal_laplace_loop (gdouble *matrix,
|
|||
*/
|
||||
static PixelRegion *
|
||||
gimp_heal_region (PixelRegion *tempPR,
|
||||
PixelRegion *srcPR)
|
||||
PixelRegion *srcPR,
|
||||
TempBuf *mask_buf)
|
||||
{
|
||||
gdouble *i_1 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
|
||||
gdouble *i_2 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
|
||||
gdouble *i_1 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
|
||||
gdouble *i_2 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
|
||||
guchar *mask = temp_buf_data (mask_buf);
|
||||
|
||||
/* substitute 0's for 1's for the division and multiplication operations that
|
||||
* come later
|
||||
|
@ -367,7 +408,7 @@ gimp_heal_region (PixelRegion *tempPR,
|
|||
gimp_heal_divide (tempPR, srcPR, i_1);
|
||||
|
||||
/* FIXME: is a faster implementation needed? */
|
||||
gimp_heal_laplace_loop (i_1, tempPR->h, tempPR->bytes, tempPR->w, i_2);
|
||||
gimp_heal_laplace_loop (i_1, tempPR->h, tempPR->bytes, tempPR->w, i_2, mask);
|
||||
|
||||
/* multiply a double by srcPR and store in tempPR */
|
||||
gimp_heal_multiply (i_2, srcPR, tempPR);
|
||||
|
@ -393,7 +434,9 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
|||
gint paint_area_width,
|
||||
gint paint_area_height)
|
||||
{
|
||||
GimpHeal *heal = GIMP_HEAL (source_core);
|
||||
GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
|
||||
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (source_core);
|
||||
GimpContext *context = GIMP_CONTEXT (paint_options);
|
||||
TempBuf *src;
|
||||
TempBuf *temp;
|
||||
|
@ -401,6 +444,10 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
|||
PixelRegion tempPR;
|
||||
PixelRegion destPR;
|
||||
GimpImageType src_type;
|
||||
TempBuf *mask_buf;
|
||||
|
||||
mask_buf = gimp_brush_core_get_brush_mask (brush_core,
|
||||
GIMP_BRUSH_HARD);
|
||||
|
||||
src_type = gimp_pickable_get_image_type (src_pickable);
|
||||
|
||||
|
@ -438,11 +485,11 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
|||
temp_buf_free (src);
|
||||
|
||||
src = temp2;
|
||||
|
||||
/* reinitialize srcPR */
|
||||
pixel_region_init_temp_buf (srcPR, src, 0, 0, src->width, src->height);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
@ -475,20 +522,27 @@ gimp_heal_motion (GimpSourceCore *source_core,
|
|||
paint_area_offset_x, paint_area_offset_y,
|
||||
paint_area_width, paint_area_height);
|
||||
|
||||
/* check that srcPR, tempPR, and destPR are the same size */
|
||||
/* check that srcPR, tempPR, destPR, and mask_buf are the same size */
|
||||
if ((srcPR->w != tempPR.w) || (srcPR->w != destPR.w) ||
|
||||
(srcPR->h != tempPR.h) || (srcPR->h != destPR.h))
|
||||
(srcPR->h != tempPR.h) || (srcPR->h != destPR.h) ||
|
||||
(srcPR->h != mask_buf->height) ||
|
||||
(srcPR->w != mask_buf->width))
|
||||
{
|
||||
/* 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 */
|
||||
g_print ("shape mismatch in gimpheal\n");
|
||||
g_print ("src width = %d\n", srcPR->w);
|
||||
g_print ("src height = %d\n", srcPR->h);
|
||||
g_print ("mask width = %d\n", mask_buf->width);
|
||||
g_print ("mask height = %d\n", mask_buf->height);
|
||||
temp_buf_free (src);
|
||||
temp_buf_free (temp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* heal tempPR using srcPR */
|
||||
gimp_heal_region (&tempPR, srcPR);
|
||||
gimp_heal_region (&tempPR, srcPR, mask_buf);
|
||||
|
||||
/* reinitialize tempPR */
|
||||
pixel_region_init_temp_buf (&tempPR, temp, 0, 0, temp->width, temp->height);
|
||||
|
|
Loading…
Reference in New Issue