Hi!

I got problems setting up a CVS gimp version (see at the bottom). The
reason I am/was trying is, that I wanted to submit a patch and
figured, you'd like it more if it was against a current CVS
version. ;-) Let me explain what my patch is about and what my
problems are at the end.

Some time ago, I tried to redo an effect someone else did with
Photoshop. It's about the surroundings ("aura" - how do pro's call
it?) of the text in the logo of Blue Twister (www.bluetwister.de).

If the server's up again, please have a look at

  http://www.bluetwister.de/images/btlogo_medium.jpg

I figured it was just a matter of the distance metric used in the
"grow selection" function - gimp would use an Eucledian metric whereas
a 4- or 8-neigbours (manhatten/checkerboard/whateveryoucallthem)
metric would have been neccessary for this effect.

So I decided to implement them and in a very easy way I succeeded. I
made the internal functions for selection growing accept an additional
parameter and since I don't know much about gtk, just implemented a
script-fu interface which I used from my website with gimp-perl.

The patch still has two problems(?):
- It is against 1.2.1
- I guess it's impossible to have optional parameters in script-fu?
  Then it'll probably be neccessary to rename the new function and
  provide the old one for backwards-compatibility.

I attached it nevertheless - please have a look whether you think
sth. like this is useful to more people than me (a gtk ui should be
trivial?) and whether you want to merge it into CVS. If you tell me
that you want the patch and you want it against CVS and you can help
me setting that version up I'd be willing to try to adopt it again
(since it's mostly done code-wise, only I can't get it to run atm).

My problem with setting up Gimp-CVS basically was, that it's not
trivial. ;-))

I installed gtk+-1.3.10, pango-0.21, atk-0.6 and stuff in the right
order - no problems so far (using pkgconfig-0.8.0 from Mdk8.1 BTW).

The Gimp compiles with some small setup-hazzles, but has at first some
strange stuff at starting up:

----------------------->8 snip 8<-----------------------
using MMX: yes

gimp (pid:11899): ** WARNING **: No fonts found by pangoft2. Things will probably not 
work

gimp (pid:11899): ** WARNING **: Didn't read any pango ft2 fontalias file. Things will 
probably not work.
gimp: query called
gimp: query done
gimp: run called extension_plugin_helper
gimp: Could not open module /usr/local/lib/gimp/1.3/plugin-modules/libiwarp.so!
gimp: time for the evil loop
gimp_dialog_factory_add_dialog: registering toplevel "gimp:toolbox"
----------------------->8 snip 8<-----------------------

Where to a newbie it seems that
- Pango has problems. (?)
- An "evil loop" can't be very nice to have ;-)

The latter lead me to plugin-helper.c:

----------------------->8 snip 8<-----------------------
        query_module ("/usr/local/lib/gimp/1.3/plugin-modules/libiwarp.so");

      g_message ("time for the evil loop");


      gimp_extension_ack ();

      while (TRUE)              /* this construction bothers me deeply */
        gimp_extension_process (0);
----------------------->8 snip 8<-----------------------

Which really seems to be strange stuff... @-}

However, the real problem is that the loading of images fails:
- GIFs have 0 layers
- JPGs are not really loaded (only the progress dialog appears, until
  I press cancel)
- The same with PNGs
- TIFs report an error "incorrect count for field MaxSampleValue (1,
  expecting 3); tag ignored" and some module segfaults (I get this:

/usr/local/lib/gimp/1.3/plug-ins/tiff: fatal error: Speicherzugriffsfehler
/usr/local/lib/gimp/1.3/plug-ins/tiff (pid:12118): [E]xit, [H]alt, show [S]tack trace 
or [P]roceed:

While I could imagine some of them are temporary problems in a
development version, I don't believe you all get all those.. ?

-- 
Ciao,  /  /
      /--/
     /  / ANS                          .,* Hamburg, Germany *,.

diff -u2bdr gimp-1.2.1/app/apptypes.h /usr/src/gimp-1.2.1-patched/app/apptypes.h
--- gimp-1.2.1/app/apptypes.h	Sat Dec 16 22:36:51 2000
+++ /usr/src/gimp-1.2.1-patched/app/apptypes.h	Tue May 22 01:02:36 2001
@@ -89,4 +89,12 @@
   NEGATIVE_CONVOL		/*  add 127 to values           */
 } ConvolutionType;
+
+/* Distance Metrics */
+typedef enum
+{
+  DIST_EUCLID,        /* Euclidean distance: sqrt((x1-x2)^2 + (y1-y2)^2) */
+  DIST_CITYBLOCK,     /* Cityblock/Manhattan distance: abs(x1-x2) + abs(y1-y2) */
+  DIST_CHECKERBOARD   /* Checkerboard distance: min(abs(x1-x2), abs(y1-y2)) */
+} DistanceMetric;

 /* Brush application types  */
Only in /usr/src/gimp-1.2.1-patched/app: apptypes.h.orig
Only in /usr/src/gimp-1.2.1-patched/app: asupsample.o
Only in /usr/src/gimp-1.2.1-patched/app: batch.o
Only in /usr/src/gimp-1.2.1-patched/app: bezier_select.o
Only in /usr/src/gimp-1.2.1-patched/app: blend.o
Only in /usr/src/gimp-1.2.1-patched/app: blob.o
Only in /usr/src/gimp-1.2.1-patched/app: boundary.o
Only in /usr/src/gimp-1.2.1-patched/app: brightness_contrast.o
Only in /usr/src/gimp-1.2.1-patched/app: brush_edit.o
Only in /usr/src/gimp-1.2.1-patched/app: brush_scale.o
Only in /usr/src/gimp-1.2.1-patched/app: brush_select.o
Only in /usr/src/gimp-1.2.1-patched/app: brush_select_cmds.o
Only in /usr/src/gimp-1.2.1-patched/app: brushes_cmds.o
Only in /usr/src/gimp-1.2.1-patched/app: bucket_fill.o
Only in /usr/src/gimp-1.2.1-patched/app: by_color_select.o
diff -u2bdr gimp-1.2.1/app/channel.c /usr/src/gimp-1.2.1-patched/app/channel.c
--- gimp-1.2.1/app/channel.c	Fri Dec 29 03:56:27 2000
+++ /usr/src/gimp-1.2.1-patched/app/channel.c	Tue Oct  9 00:57:42 2001
@@ -1540,5 +1540,6 @@
 channel_grow (Channel *mask,
 	      gint     radius_x,
-	      gint     radius_y)
+	      gint     radius_y,
+	      DistanceMetric metric)
 {
   PixelRegion bPR;
@@ -1550,5 +1551,5 @@
   if (radius_x <= 0 && radius_y <= 0)
     {
-      channel_shrink (mask, -radius_x, -radius_y, FALSE);
+      channel_shrink (mask, -radius_x, -radius_y, metric, FALSE);
       return;
     }
@@ -1586,5 +1587,5 @@
 		     (y2 - y1), TRUE);

-  fatten_region (&bPR, radius_x, radius_y);
+  fatten_region (&bPR, radius_x, radius_y, metric);

   mask->bounds_known = FALSE;
@@ -1595,4 +1596,5 @@
 		gint      radius_x,
 		gint      radius_y,
+		DistanceMetric metric,
 		gboolean  edge_lock)
 {
@@ -1605,5 +1607,5 @@
   if (radius_x <= 0 && radius_y <= 0)
     {
-      channel_grow (mask, -radius_x, -radius_y);
+      channel_grow (mask, -radius_x, -radius_y, metric);
       return;
     }
@@ -1632,5 +1634,5 @@
 		     (y2 - y1), TRUE);

-  thin_region (&bPR, radius_x, radius_y, edge_lock);
+  thin_region (&bPR, radius_x, radius_y, metric, edge_lock);

   mask->bounds_known = FALSE;
diff -u2bdr gimp-1.2.1/app/channel.h /usr/src/gimp-1.2.1-patched/app/channel.h
--- gimp-1.2.1/app/channel.h	Sat Dec 16 22:36:51 2000
+++ /usr/src/gimp-1.2.1-patched/app/channel.h	Tue Oct  9 00:55:43 2001
@@ -192,8 +192,10 @@
 void            channel_grow            (Channel   *mask,
 					 gint       radius_x,
-					 gint       radius_y);
+					 gint       radius_y,
+					 DistanceMetric metric);
 void            channel_shrink          (Channel   *mask,
 					 gint       radius_x,
 					 gint       radius_y,
+					 DistanceMetric metric,
 					 gboolean   edge_lock);

diff -u2bdr gimp-1.2.1/app/commands.c /usr/src/gimp-1.2.1-patched/app/commands.c
--- gimp-1.2.1/app/commands.c	Sun Dec 24 21:27:03 2000
+++ /usr/src/gimp-1.2.1-patched/app/commands.c	Tue Oct  9 00:58:49 2001
@@ -1455,5 +1455,5 @@
     }

-  gimage_mask_grow (gimage, radius_x, radius_y);
+  gimage_mask_grow (gimage, radius_x, radius_y, DIST_EUCLID);
   gdisplays_flush ();
 }
@@ -1492,5 +1492,5 @@
     }

-  gimage_mask_shrink (gimage, radius_x, radius_y, selection_shrink_edge_lock);
+  gimage_mask_shrink (gimage, radius_x, radius_y, DIST_EUCLID, selection_shrink_edge_lock);
   gdisplays_flush ();
 }
diff -u2bdr gimp-1.2.1/app/gimage_mask.c /usr/src/gimp-1.2.1-patched/app/gimage_mask.c
--- gimp-1.2.1/app/gimage_mask.c	Sat Dec 16 22:36:53 2000
+++ /usr/src/gimp-1.2.1-patched/app/gimage_mask.c	Tue Oct  9 00:36:35 2001
@@ -462,10 +462,12 @@
 gimage_mask_grow (GImage *gimage,
 		  int     grow_pixels_x,
-		  int     grow_pixels_y)
+		  int     grow_pixels_y,
+		  DistanceMetric metric)
 {
   /*  feather the region  */
   channel_grow (gimage_get_mask (gimage),
 		grow_pixels_x,
-		grow_pixels_y);
+		grow_pixels_y,
+		metric);
 }

@@ -475,4 +477,5 @@
 		    gint      shrink_pixels_x,
 		    gint      shrink_pixels_y,
+		    DistanceMetric metric,
 		    gboolean  edge_lock)
 {
@@ -481,4 +484,5 @@
 		  shrink_pixels_x,
 		  shrink_pixels_y,
+		  metric,
 		  edge_lock);
 }
Only in /usr/src/gimp-1.2.1-patched/app: gimage_mask.c~
diff -u2bdr gimp-1.2.1/app/gimage_mask.h /usr/src/gimp-1.2.1-patched/app/gimage_mask.h
--- gimp-1.2.1/app/gimage_mask.h	Sun Mar 26 20:39:02 2000
+++ /usr/src/gimp-1.2.1-patched/app/gimage_mask.h	Tue Oct  9 00:38:18 2001
@@ -75,9 +75,11 @@
 void            gimage_mask_grow          (GImage       *gimage,
 					   gint           grow_pixels_x,
-					   gint           grow_pixels_y);
+					   gint           grow_pixels_y,
+					   DistanceMetric metric);

 void            gimage_mask_shrink        (GImage       *gimage,
 					   gint          shrink_pixels_x,
 					   gint          shrink_pixels_y,
+					   DistanceMetric metric,
 					   gboolean      edge_lock);

diff -u2bdr gimp-1.2.1/app/paint_funcs.c /usr/src/gimp-1.2.1-patched/app/paint_funcs.c
--- gimp-1.2.1/app/paint_funcs.c	Sat Dec 16 22:36:54 2000
+++ /usr/src/gimp-1.2.1-patched/app/paint_funcs.c	Tue Oct  9 00:32:08 2001
@@ -4539,9 +4539,12 @@

 static void
-compute_border(gint16 *circ, guint16 xradius, guint16 yradius)
+compute_border(gint16 *border, guint16 xradius, guint16 yradius,
+	       DistanceMetric metric)
 {
   gint32 i;
   gint32 diameter = xradius*2 +1;
   gdouble tmp;
+  switch (metric) {
+  case DIST_EUCLID: /* eucleadian distance */
   for (i = 0; i < diameter; i++)
   {
@@ -4552,11 +4555,37 @@
     else
       tmp = 0.0;
-    circ[i] = RINT(yradius/(double)xradius *
+		  border[i] = RINT(yradius/(double)xradius *
 		   sqrt((xradius)*(xradius) - (tmp)*(tmp)));
   }
+	  break;
+  case DIST_CITYBLOCK: /* cityblock distance */
+	  for (i = 0; i < diameter; i++)
+	  {
+		  if (i > xradius)
+			  tmp = (i - xradius) - .5;
+		  else if (i < xradius)
+			  tmp = (xradius - i) - .5;
+		  else
+			  tmp = 0.0;
+		  border[i] = RINT((double)yradius*(xradius-tmp)/xradius);
+	  }
+	  break;
+  case DIST_CHECKERBOARD: /* checkerboard distance */
+	  for (i = 0; i < diameter; i++)
+	  {
+		  if (i > xradius)
+			  tmp = (i - xradius) - .5;
+		  else if (i < xradius)
+			  tmp = (xradius - i) - .5;
+		  else
+			  tmp = 0.0;
+		  border[i] = RINT((double)yradius);
+	  }
+  }
 }

 void
-fatten_region(PixelRegion *src, gint16 xradius, gint16 yradius)
+fatten_region(PixelRegion *src, gint16 xradius, gint16 yradius,
+	      DistanceMetric metric)
 {
 /*
@@ -4568,5 +4597,5 @@
   guchar *out;  /* holds the new scan line we are computing */
   guchar **max; /* caches the largest values for each column */
-  gint16 *circ; /* holds the y coords of the filter's mask */
+  gint16 *border; /* holds the y coords of the filter's mask */
   gint16 last_max, last_index;

@@ -4601,10 +4630,10 @@
   out =  (guchar *)g_malloc (src->w * sizeof(guchar));

-  circ = (short *)g_malloc ((2*xradius + 1) * sizeof(gint16));
-  compute_border (circ, xradius, yradius);
+  border = (short *)g_malloc ((2*xradius + 1) * sizeof(gint16));
+  compute_border (border, xradius, yradius, metric);

- /* offset the circ pointer by xradius so the range of the array
+ /* offset the border pointer by xradius so the range of the array
     is [-xradius] to [xradius] */
-  circ += xradius;
+  border += xradius;

   memset (buf[0], 0, src->w);
@@ -4637,5 +4666,5 @@
       max[x][0] = buf[0][x];
     }
-    last_max =  max[0][circ[-1]];
+    last_max =  max[0][border[-1]];
     last_index = 1;
     for (x = 0 ; x < src->w; x++) /* render scan line */
@@ -4650,7 +4679,7 @@
 	  last_max = 0;
 	  for (i = xradius; i >= 0; i--)
-	    if (last_max < max[x+i][circ[i]])
+	    if (last_max < max[x+i][border[i]])
 	    {
-	      last_max = max[x+i][circ[i]];
+	      last_max = max[x+i][border[i]];
 	      last_index = i;
 	    }
@@ -4661,9 +4690,9 @@
       {
 	last_index = xradius;
-	last_max = max[x+xradius][circ[xradius]];
+	last_max = max[x+xradius][border[xradius]];
 	for (i = xradius-1; i >= -xradius; i--)
-	  if (last_max < max[x+i][circ[i]])
+	  if (last_max < max[x+i][border[i]])
 	  {
-	    last_max = max[x+i][circ[i]];
+	    last_max = max[x+i][border[i]];
 	    last_index = i;
 	  }
@@ -4674,8 +4703,8 @@
   }
   /* undo the offsets to the pointers so we can free the malloced memmory */
-  circ -= xradius;
+  border -= xradius;
   max -= xradius;

-  g_free (circ);
+  g_free (border);
   g_free (buffer);
   g_free (max);
@@ -4687,5 +4716,6 @@

 void
-thin_region(PixelRegion *src, gint16 xradius, gint16 yradius, int edge_lock)
+thin_region(PixelRegion *src, gint16 xradius, gint16 yradius,
+	    DistanceMetric metric, int edge_lock)
 {
 /*
@@ -4701,5 +4731,5 @@
   guchar *out;  /* holds the new scan line we are computing */
   guchar **max; /* caches the smallest values for each column */
-  gint16 *circ; /* holds the y coords of the filter's mask */
+  gint16 *border; /* holds the y coords of the filter's mask */
   gint16 last_max, last_index;

@@ -4745,10 +4775,10 @@
   out = (guchar *)g_malloc(src->w);

-  circ = (short *)g_malloc((2*xradius + 1)*sizeof(gint16));
-  compute_border(circ, xradius, yradius);
+  border = (short *)g_malloc((2*xradius + 1)*sizeof(gint16));
+  compute_border(border, xradius, yradius, metric);

- /* offset the circ pointer by xradius so the range of the array
+ /* offset the border pointer by xradius so the range of the array
     is [-xradius] to [xradius] */
-  circ += xradius;
+  border += xradius;

   for (i = 0; i < yradius && i < src->h; i++) /* load top of image */
@@ -4785,5 +4815,5 @@
       max[x][0] = buf[0][x];
     }
-    last_max =  max[0][circ[-1]];
+    last_max =  max[0][border[-1]];
     last_index = 0;
     for (x = 0 ; x < src->w; x++) /* render scan line */
@@ -4798,7 +4828,7 @@
 	  last_max = 255;
 	  for (i = xradius; i >= 0; i--)
-	    if (last_max > max[x+i][circ[i]])
+	    if (last_max > max[x+i][border[i]])
 	    {
-	      last_max = max[x+i][circ[i]];
+	      last_max = max[x+i][border[i]];
 	      last_index = i;
 	    }
@@ -4809,9 +4839,9 @@
       {
 	last_index = xradius;
-	last_max = max[x+xradius][circ[xradius]];
+	last_max = max[x+xradius][border[xradius]];
 	for (i = xradius-1; i >= -xradius; i--)
-	  if (last_max > max[x+i][circ[i]])
+	  if (last_max > max[x+i][border[i]])
 	  {
-	    last_max = max[x+i][circ[i]];
+	    last_max = max[x+i][border[i]];
 	    last_index = i;
 	  }
@@ -4822,8 +4852,8 @@
   }
   /* undo the offsets to the pointers so we can free the malloced memmory */
-  circ -= xradius;
+  border -= xradius;
   max -= xradius;
   /* free the memmory */
-  g_free (circ);
+  g_free (border);
   g_free (buffer);
   g_free (max);
Only in /usr/src/gimp-1.2.1-patched/app: paint_funcs.c.orig
Only in /usr/src/gimp-1.2.1-patched/app: paint_funcs.c~
diff -u2bdr gimp-1.2.1/app/paint_funcs.h /usr/src/gimp-1.2.1-patched/app/paint_funcs.h
--- gimp-1.2.1/app/paint_funcs.h	Sat Dec 16 22:36:54 2000
+++ /usr/src/gimp-1.2.1-patched/app/paint_funcs.h	Tue May 22 00:58:39 2001
@@ -501,8 +501,8 @@

 void thin_region                           (PixelRegion *, gint16 xradius,
-					    gint16 yradius, int edge_lock);
+					    gint16 yradius, DistanceMetric metric, int edge_lock);

 void fatten_region                         (PixelRegion *,
-					    gint16 xradius, gint16 yradius);
+					    gint16 xradius, gint16 yradius, DistanceMetric metric);

 void  swap_region                         (PixelRegion *, PixelRegion *);
diff -u2bdr gimp-1.2.1/app/selection_cmds.c /usr/src/gimp-1.2.1-patched/app/selection_cmds.c
--- gimp-1.2.1/app/selection_cmds.c	Thu Jun  1 14:20:09 2000
+++ /usr/src/gimp-1.2.1-patched/app/selection_cmds.c	Tue Oct  9 01:03:14 2001
@@ -722,5 +722,5 @@
   gboolean success = TRUE;
   GimpImage *gimage;
-  gint32 steps;
+  gint32 steps, metric;

   gimage = pdb_id_to_image (args[0].value.pdb_int);
@@ -732,6 +732,10 @@
     success = FALSE;

+  metric = args[2].value.pdb_int;
+  if (metric < 0)
+    metric = 0;
+
   if (success)
-    gimage_mask_grow (gimage, steps, steps);
+    gimage_mask_grow (gimage, steps, steps, metric);

   return procedural_db_return_args (&selection_grow_proc, success);
@@ -749,4 +753,9 @@
     "steps",
     "Steps of grow (in pixels)"
+  },
+  {
+    PDB_INT32,
+    "metric",
+    "distance metric to be used: DIST_EUCLID(0), DIST_CITYBLOCK(1) or DIST_CHECKERBOARD(2)"
   }
 };
@@ -756,10 +765,10 @@
   "gimp_selection_grow",
   "Grow the image's selection",
-  "This procedure grows the selection. Growing involves expanding the boundary in all directions by the specified pixel amount.",
-  "Spencer Kimball & Peter Mattis",
-  "Spencer Kimball & Peter Mattis",
+  "This procedure grows the selection. Growing involves expanding the boundary in all directions by the specified pixel amount (measured in given distance metric).",
+  "Spencer Kimball & Peter Mattis, Hans Meine",
+  "Spencer Kimball & Peter Mattis, Hans Meine",
   "1995-1996",
   PDB_INTERNAL,
-  2,
+  3,
   selection_grow_inargs,
   0,
@@ -773,5 +782,5 @@
   gboolean success = TRUE;
   GimpImage *gimage;
-  gint32 radius;
+  gint32 radius, metric;

   gimage = pdb_id_to_image (args[0].value.pdb_int);
@@ -783,6 +792,10 @@
     success = FALSE;

+  metric = args[2].value.pdb_int;
+  if (metric < 0)
+    metric = 0;
+
   if (success)
-    gimage_mask_shrink (gimage, radius, radius, FALSE);
+    gimage_mask_shrink (gimage, radius, radius, metric, FALSE);

   return procedural_db_return_args (&selection_shrink_proc, success);
@@ -800,4 +813,9 @@
     "radius",
     "Radius of shrink (in pixels)"
+  },
+  {
+    PDB_INT32,
+    "metric",
+    "distance metric to be used: DIST_EUCLID(0), DIST_CITYBLOCK(1) or DIST_CHECKERBOARD(2)"
   }
 };
@@ -807,10 +825,10 @@
   "gimp_selection_shrink",
   "Shrink the image's selection",
-  "This procedure shrinks the selection. Shrinking invovles trimming the existing selection boundary on all sides by the specified number of pixels.",
-  "Spencer Kimball & Peter Mattis",
-  "Spencer Kimball & Peter Mattis",
+  "This procedure shrinks the selection. Shrinking invovles trimming the existing selection boundary on all sides by the specified number of pixels (measured in given distance metric).",
+  "Spencer Kimball & Peter Mattis, Hans Meine",
+  "Spencer Kimball & Peter Mattis, Hans Meine",
   "1995-1996",
   PDB_INTERNAL,
-  2,
+  3,
   selection_shrink_inargs,
   0,

Reply via email to