added erode_region() and dilate_region()

This commit is contained in:
Sven Neumann 2005-07-14 15:40:19 +00:00
parent c692d9cdac
commit 2566531777
4 changed files with 151 additions and 5 deletions

View File

@ -1,3 +1,11 @@
2005-07-14 Sven Neumann <sven@gimp.org>
* app/paint-funcs/paint-funcs.[ch]: added erode_region() and
dilate_region(). Less general than thin_region() and fatten_region()
but a little faster.
* app/base/siox.c: use the new functions.
2005-07-14 Michael Natterer <mitch@gimp.org>
* app/widgets/Makefile.am

View File

@ -16,6 +16,8 @@
* by Gerald Friedland <fland@inf.fu-berlin.de>
* and Kristian Jantz <jantz@inf.fu-berlin.de>.
*
* Adapted for GIMP by Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -649,8 +651,7 @@ erode_mask (TileManager *mask,
pixel_region_init (&region, mask, x, y, width, height, TRUE);
/* inefficient */
thin_region (&region, 1, 1, TRUE);
erode_region (&region);
}
static void
@ -664,8 +665,7 @@ dilate_mask (TileManager *mask,
pixel_region_init (&region, mask, x, y, width, height, TRUE);
/* inefficient */
fatten_region (&region, 1, 1);
dilate_region (&region);
}
static void

View File

@ -3350,7 +3350,7 @@ smooth_region (PixelRegion *region)
memcpy (buf[2], buf[1], width + 2);
}
for (x = 0 ; x < width; x++) /* render scan line */
for (x = 0 ; x < width; x++)
{
gint value = (buf[0][x] + buf[0][x+1] + buf[0][x+2] +
buf[1][x] + buf[2][x+1] + buf[1][x+2] +
@ -3370,6 +3370,142 @@ smooth_region (PixelRegion *region)
g_free (out);
}
/* Erode (radius 1 pixel) a mask (1bpp). */
void
erode_region (PixelRegion *region)
{
gint x, y;
gint width;
gint i;
guchar *buf[3];
guchar *out;
width = region->w;
for (i = 0; i < 3; i++)
buf[i] = g_new (guchar, width + 2);
out = g_new (guchar, width);
/* load top of image */
pixel_region_get_row (region, region->x, region->y, width, buf[0] + 1, 1);
buf[0][0] = buf[0][1];
buf[0][width + 1] = buf[0][width];
memcpy (buf[1], buf[2], width + 2);
for (y = 0; y < region->h; y++)
{
if (y + 1 < region->h)
{
pixel_region_get_row (region, region->x, region->y + y + 1, width,
buf[2] + 1, 1);
buf[2][0] = buf[2][1];
buf[2][width + 1] = buf[2][width];
}
else
{
memcpy (buf[2], buf[1], width + 2);
}
for (x = 0 ; x < width; x++)
{
gint min = 255;
if (buf[0][x] < min) min = buf[0][x];
if (buf[0][x+1] < min) min = buf[0][x+1];
if (buf[0][x+2] < min) min = buf[0][x+2];
if (buf[1][x] < min) min = buf[1][x];
if (buf[1][x+1] < min) min = buf[1][x+1];
if (buf[1][x+2] < min) min = buf[1][x+2];
if (buf[2][x] < min) min = buf[2][x];
if (buf[2][x+1] < min) min = buf[2][x+1];
if (buf[2][x+2] < min) min = buf[2][x+2];
out[x] = min;
}
pixel_region_set_row (region, region->x, region->y + y, width, out);
rotate_pointers (buf, 3);
}
for (i = 0; i < 3; i++)
g_free (buf[i]);
g_free (out);
}
/* Dilate (radius 1 pixel) a mask (1bpp). */
void
dilate_region (PixelRegion *region)
{
gint x, y;
gint width;
gint i;
guchar *buf[3];
guchar *out;
width = region->w;
for (i = 0; i < 3; i++)
buf[i] = g_new (guchar, width + 2);
out = g_new (guchar, width);
/* load top of image */
pixel_region_get_row (region, region->x, region->y, width, buf[0] + 1, 1);
buf[0][0] = buf[0][1];
buf[0][width + 1] = buf[0][width];
memcpy (buf[1], buf[2], width + 2);
for (y = 0; y < region->h; y++)
{
if (y + 1 < region->h)
{
pixel_region_get_row (region, region->x, region->y + y + 1, width,
buf[2] + 1, 1);
buf[2][0] = buf[2][1];
buf[2][width + 1] = buf[2][width];
}
else
{
memcpy (buf[2], buf[1], width + 2);
}
for (x = 0 ; x < width; x++)
{
gint max = 0;
if (buf[0][x] < max) max = buf[0][x];
if (buf[0][x+1] < max) max = buf[0][x+1];
if (buf[0][x+2] < max) max = buf[0][x+2];
if (buf[1][x] < max) max = buf[1][x];
if (buf[1][x+1] < max) max = buf[1][x+1];
if (buf[1][x+2] < max) max = buf[1][x+2];
if (buf[2][x] < max) max = buf[2][x];
if (buf[2][x+1] < max) max = buf[2][x+1];
if (buf[2][x+2] < max) max = buf[2][x+2];
out[x] = max;
}
pixel_region_set_row (region, region->x, region->y + y, width, out);
rotate_pointers (buf, 3);
}
for (i = 0; i < 3; i++)
g_free (buf[i]);
g_free (out);
}
static void
compute_transition (guchar *transition,
guchar **buf,

View File

@ -388,6 +388,8 @@ void fatten_region (PixelRegion *region,
gint16 yradius);
void smooth_region (PixelRegion *region);
void erode_region (PixelRegion *region);
void dilate_region (PixelRegion *region);
void swap_region (PixelRegion *src,
PixelRegion *dest);