mirror of https://github.com/GNOME/gimp.git
added erode_region() and dilate_region()
This commit is contained in:
parent
c692d9cdac
commit
2566531777
|
@ -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
|
||||
|
|
|
@ -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 (®ion, mask, x, y, width, height, TRUE);
|
||||
|
||||
/* inefficient */
|
||||
thin_region (®ion, 1, 1, TRUE);
|
||||
erode_region (®ion);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -664,8 +665,7 @@ dilate_mask (TileManager *mask,
|
|||
|
||||
pixel_region_init (®ion, mask, x, y, width, height, TRUE);
|
||||
|
||||
/* inefficient */
|
||||
fatten_region (®ion, 1, 1);
|
||||
dilate_region (®ion);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue