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,