gimp r25308 - in branches/gimp-2-4: . app/paint



Author: neo
Date: Sun Mar 30 14:36:30 2008
New Revision: 25308
URL: http://svn.gnome.org/viewvc/gimp?rev=25308&view=rev

Log:
2008-03-30  Sven Neumann  <sven gimp org>

	Merged Bill's changes for bug #521433 from trunk with some minor
	cleanups:

	* app/paint/gimpbrushcore.[ch]: made
	gimp_brush_core_get_brush_mask() public.

	* app/paint/gimpheal.c: respect the brush mask.



Modified:
   branches/gimp-2-4/ChangeLog
   branches/gimp-2-4/app/paint/gimpbrushcore.c
   branches/gimp-2-4/app/paint/gimpbrushcore.h
   branches/gimp-2-4/app/paint/gimpheal.c

Modified: branches/gimp-2-4/app/paint/gimpbrushcore.c
==============================================================================
--- branches/gimp-2-4/app/paint/gimpbrushcore.c	(original)
+++ branches/gimp-2-4/app/paint/gimpbrushcore.c	Sun Mar 30 14:36:30 2008
@@ -108,8 +108,6 @@
 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);
 
@@ -1354,13 +1352,17 @@
   return core->scale_pixmap;
 }
 
-static TempBuf *
+TempBuf *
 gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
                                 GimpBrushApplicationMode  brush_hardness)
 {
-  GimpPaintCore *paint_core = GIMP_PAINT_CORE (core);
+  GimpPaintCore *paint_core;
   TempBuf       *mask;
 
+  g_return_val_if_fail (GIMP_IS_BRUSH_CORE (core), NULL);
+
+  paint_core = GIMP_PAINT_CORE (core);
+
   mask = gimp_brush_core_scale_mask (core, core->brush);
 
   if (! mask)

Modified: branches/gimp-2-4/app/paint/gimpbrushcore.h
==============================================================================
--- branches/gimp-2-4/app/paint/gimpbrushcore.h	(original)
+++ branches/gimp-2-4/app/paint/gimpbrushcore.h	Sun Mar 30 14:36:30 2008
@@ -126,5 +126,8 @@
                                         TempBuf                  *area,
                                         GimpBrushApplicationMode  mode);
 
+TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
+                                          GimpBrushApplicationMode  brush_hardness);
+
 
 #endif  /*  __GIMP_BRUSH_CORE_H__  */

Modified: branches/gimp-2-4/app/paint/gimpheal.c
==============================================================================
--- branches/gimp-2-4/app/paint/gimpheal.c	(original)
+++ branches/gimp-2-4/app/paint/gimpheal.c	Sun Mar 30 14:36:30 2008
@@ -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 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 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);
+
+
+
 
 
 G_DEFINE_TYPE (GimpHeal, gimp_heal, GIMP_TYPE_SOURCE_CORE)
@@ -268,7 +304,8 @@
                              gint     height,
                              gint     depth,
                              gint     width,
-                             gdouble *solution)
+                             gdouble *solution,
+                             guchar  *mask)
 {
   gint     rowstride = width * depth;
   gint     i, j, k;
@@ -279,10 +316,10 @@
     {
       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 @@
           /* advance pointers to data */
           matrix += depth;
           solution += depth;
+          mask++;
         }
     }
 
@@ -322,7 +360,8 @@
                         gint     height,
                         gint     depth,
                         gint     width,
-                        gdouble *solution)
+                        gdouble *solution,
+                        guchar  *mask)
 {
 #define EPSILON   0.0001
 #define MAX_ITER  500
@@ -334,8 +373,8 @@
       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 @@
  */
 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_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,6 +434,7 @@
                   gint              paint_area_width,
                   gint              paint_area_height)
 {
+  GimpHeal      *heal       = GIMP_HEAL (source_core);
   GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core);
   GimpContext   *context    = GIMP_CONTEXT (paint_options);
   TempBuf       *src;
@@ -401,6 +443,10 @@
   PixelRegion    tempPR;
   PixelRegion    destPR;
   GimpImageType  src_type;
+  TempBuf       *mask_buf;
+
+  mask_buf = gimp_brush_core_get_brush_mask (GIMP_BRUSH_CORE (source_core),
+                                             GIMP_BRUSH_HARD);
 
   src_type = gimp_pickable_get_image_type (src_pickable);
 
@@ -438,11 +484,11 @@
         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 +521,24 @@
                               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 */
+
       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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]