Commit 40dbda9e authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

app/base/base-enums.h app/base/siox.[ch]

2005-10-17  Sven Neumann  <sven@gimp.org>

	* app/base/base-enums.h
	* app/base/siox.[ch]
	* app/core/gimpdrawable-foreground-extract.[ch]
	* app/tools/gimpforegroundselecttool.[ch]: export stateful SIOX to
	the core API and use it from the foreground selection tool.
parent 5a6bd93e
2005-10-17 Sven Neumann <sven@gimp.org>
* app/base/base-enums.h
* app/base/siox.[ch]
* app/core/gimpdrawable-foreground-extract.[ch]
* app/tools/gimpforegroundselecttool.[ch]: export stateful SIOX to
the core API and use it from the foreground selection tool.
2005-10-17 Sven Neumann <sven@gimp.org>
* app/base/base.c (base_init)
......
......@@ -118,5 +118,15 @@ typedef enum /*< skip >*/
GIMP_MAGENTA_HUES
} GimpHueRange;
typedef enum /*< pdb-skip, skip >*/
{
SIOX_REFINEMENT_NO_CHANGE = 0,
SIOX_REFINEMENT_ADD_FOREGROUND = (1 << 0),
SIOX_REFINEMENT_ADD_BACKGROUND = (1 << 1),
SIOX_REFINEMENT_CHANGE_SENSITIVITY = (1 << 2),
SIOX_REFINEMENT_CHANGE_SMOOTHNESS = (1 << 3),
SIOX_REFINEMENT_CHANGE_MULTIBLOB = (1 << 4),
SIOX_REFINEMENT_RECALCULATE = 0xFF
} SioxRefinementType;
#endif /* __BASE_ENUMS_H__ */
This diff is collapsed.
......@@ -43,45 +43,39 @@
#define SIOX_DEFAULT_SENSITIVITY_A 1.28
#define SIOX_DEFAULT_SENSITIVITY_B 2.56
#define SIOX_REFINEMENT_TYPE_NO_CHANGE 0
#define SIOX_REFINEMENT_TYPE_ADD_FOREGROUND (1 << 0)
#define SIOX_REFINEMENT_TYPE_ADD_BACKGROUND (1 << 1)
#define SIOX_REFINEMENT_TYPE_CHANGE_SENSITIVITY (1 << 2)
#define SIOX_REFINEMENT_TYPE_CHANGE_SMOOTHNESS (1 << 3)
#define SIOX_REFINEMENT_TYPE_CHANGE_MULTIBLOB (1 << 4)
#define SIOX_REFINEMENT_TYPE_RECALCULATE 0xFF
/* FIXME: turn this into an enum */
#define SIOX_DRB_ADD 0
#define SIOX_DRB_SUBTRACT 1
#define SIOX_DRB_ADD 0
#define SIOX_DRB_SUBTRACT 1
typedef void (* SioxProgressFunc) (gpointer progress_data,
gdouble fraction);
SioxState * siox_init (TileManager *pixels,
const guchar *colormap,
gint offset_x,
gint offset_y,
TileManager *mask,
gint x,
gint y,
gint width,
gint height,
SioxProgressFunc progress_callback,
gpointer progress_data);
void siox_foreground_extract (SioxState *state,
gint smoothness,
const gdouble sensitivity[3],
gboolean multiblob,
gint refinementtype);
void siox_drb (SioxState *state,
gint x,
gint y,
gint brushradius,
gint brushmode,
gfloat threshold);
void siox_done (SioxState *state);
SioxState * siox_init (TileManager *pixels,
const guchar *colormap,
gint offset_x,
gint offset_y,
gint x,
gint y,
gint width,
gint height);
void siox_foreground_extract (SioxState *state,
SioxRefinementType refinement,
TileManager *mask,
gint smoothness,
const gdouble sensitivity[3],
gboolean multiblob,
SioxProgressFunc progress_callback,
gpointer progress_data);
void siox_done (SioxState *state);
void siox_drb (SioxState *state,
TileManager *mask,
gint x,
gint y,
gint brush_radius,
gint brush_mode,
gfloat threshold);
#endif /* __SIOX_H__ */
......@@ -45,6 +45,7 @@ gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpDrawable *mask,
GimpProgress *progress)
{
SioxState *state;
const gdouble sensitivity[3] = { SIOX_DEFAULT_SENSITIVITY_L,
SIOX_DEFAULT_SENSITIVITY_A,
SIOX_DEFAULT_SENSITIVITY_B };
......@@ -52,42 +53,40 @@ gimp_drawable_foreground_extract (GimpDrawable *drawable,
g_return_if_fail (GIMP_IS_DRAWABLE (mask));
g_return_if_fail (mode == GIMP_FOREGROUND_EXTRACT_SIOX);
gimp_drawable_foreground_extract_siox (drawable, mask,
0, 0,
gimp_item_width (GIMP_ITEM (mask)),
gimp_item_height (GIMP_ITEM (mask)),
FALSE,
SIOX_DEFAULT_SMOOTHNESS,
sensitivity,
progress);
state =
gimp_drawable_foreground_extract_siox_init (drawable,
0, 0,
gimp_item_width (GIMP_ITEM (mask)),
gimp_item_height (GIMP_ITEM (mask)));
if (state)
{
gimp_drawable_foreground_extract_siox (mask, state,
SIOX_REFINEMENT_RECALCULATE,
SIOX_DEFAULT_SMOOTHNESS,
sensitivity,
FALSE,
progress);
gimp_drawable_foreground_extract_siox_done (state);
}
}
void
gimp_drawable_foreground_extract_siox (GimpDrawable *drawable,
GimpDrawable *mask,
gint x,
gint y,
gint width,
gint height,
gboolean multiblob,
gint smoothness,
const gdouble sensitivity[3],
GimpProgress *progress)
SioxState *
gimp_drawable_foreground_extract_siox_init (GimpDrawable *drawable,
gint x,
gint y,
gint width,
gint height)
{
GimpImage *gimage;
SioxState *state;
const guchar *colormap = NULL;
gboolean intersect;
gint offset_x;
gint offset_y;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
g_return_if_fail (GIMP_IS_DRAWABLE (mask));
g_return_if_fail (gimp_drawable_bytes (mask) == 1);
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
......@@ -108,19 +107,36 @@ gimp_drawable_foreground_extract_siox (GimpDrawable *drawable,
*/
if (! intersect)
return;
return NULL;
return siox_init (gimp_drawable_data (drawable), colormap,
offset_x, offset_y,
x, y, width, height);
}
void
gimp_drawable_foreground_extract_siox (GimpDrawable *mask,
SioxState *state,
SioxRefinementType refinement,
gint smoothness,
const gdouble sensitivity[3],
gboolean multiblob,
GimpProgress *progress)
{
g_return_if_fail (GIMP_IS_DRAWABLE (mask));
g_return_if_fail (gimp_drawable_bytes (mask) == 1);
g_return_if_fail (state != NULL);
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
if (progress)
gimp_progress_start (progress, _("Foreground Extraction"), FALSE);
state = siox_init (gimp_drawable_data (drawable), colormap,
offset_x, offset_y,
gimp_drawable_data (mask), x, y, width, height,
(SioxProgressFunc) gimp_progress_set_value,
progress);
siox_foreground_extract (state, smoothness, sensitivity, multiblob, 255);
siox_done (state);
siox_foreground_extract (state, refinement, gimp_drawable_data (mask),
smoothness, sensitivity, multiblob,
(SioxProgressFunc) gimp_progress_set_value,
progress);
if (progress)
gimp_progress_end (progress);
......@@ -130,3 +146,11 @@ gimp_drawable_foreground_extract_siox (GimpDrawable *drawable,
gimp_item_width (GIMP_ITEM (mask)),
gimp_item_height (GIMP_ITEM (mask)));
}
void
gimp_drawable_foreground_extract_siox_done (SioxState *state)
{
g_return_if_fail (state != NULL);
siox_done (state);
}
......@@ -20,21 +20,28 @@
#define __GIMP_DRAWABLE_FOREGROUND_EXTRACT_H__
void gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpForegroundExtractMode mode,
GimpDrawable *mask,
GimpProgress *progress);
/* variant for SIOX that gives more control over the segmentation */
void gimp_drawable_foreground_extract_siox (GimpDrawable *drawable,
GimpDrawable *mask,
gint x,
gint y,
gint width,
gint height,
gboolean multiblob,
gint smoothness,
const gdouble sensitivity[3],
GimpProgress *progress);
/* general API (as seen from the PDB) */
void gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpForegroundExtractMode mode,
GimpDrawable *mask,
GimpProgress *progress);
/* SIOX specific API */
SioxState * gimp_drawable_foreground_extract_siox_init (GimpDrawable *drawable,
gint x,
gint y,
gint width,
gint height);
void gimp_drawable_foreground_extract_siox (GimpDrawable *mask,
SioxState *state,
SioxRefinementType refinemane,
gint smoothness,
const gdouble sensitivity[3],
gboolean multiblob,
GimpProgress *progress);
void gimp_drawable_foreground_extract_siox_done (SioxState *state);
#endif /* __GIMP_DRAWABLE_FOREGROUND_EXTRACT_H__ */
......@@ -249,6 +249,9 @@ gimp_foreground_select_tool_finalize (GObject *object)
if (fg_select->strokes)
g_warning ("%s: strokes should be NULL at this point", G_STRLOC);
if (fg_select->state)
g_warning ("%s: state should be NULL at this point", G_STRLOC);
if (fg_select->mask)
g_warning ("%s: mask should be NULL at this point", G_STRLOC);
......@@ -280,6 +283,12 @@ gimp_foreground_select_tool_control (GimpTool *tool,
g_list_free (fg_select->strokes);
fg_select->strokes = NULL;
if (fg_select->state)
{
gimp_drawable_foreground_extract_siox_done (fg_select->state);
fg_select->state = NULL;
}
}
break;
......@@ -636,31 +645,41 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
if (fg_select->strokes)
{
GList *list;
gint x1, y1;
gint x2, y2;
gimp_set_busy (gimage->gimp);
/* restrict working area to double the size of the bounding box */
gimp_foreground_select_tool_get_area (mask, &x1, &y1, &x2, &y2);
/* apply foreground and background markers */
for (list = fg_select->strokes; list; list = list->next)
gimp_foreground_select_tool_stroke (mask, list->data);
gimp_drawable_foreground_extract_siox (drawable,
GIMP_DRAWABLE (mask),
x1, y1, x2 - x1, y2 - y1,
options->multiblob,
options->smoothness,
options->sensitivity,
GIMP_PROGRESS (gdisp));
if (fg_select->state)
gimp_drawable_foreground_extract_siox (GIMP_DRAWABLE (mask),
fg_select->state,
fg_select->refinement,
options->smoothness,
options->sensitivity,
options->multiblob,
GIMP_PROGRESS (gdisp));
fg_select->refinement = SIOX_REFINEMENT_NO_CHANGE;
gimp_unset_busy (gimage->gimp);
}
else
{
gint x1, y1;
gint x2, y2;
g_object_set (options, "background", FALSE, NULL);
gimp_foreground_select_tool_get_area (mask, &x1, &y1, &x2, &y2);
if (fg_select->state)
g_warning ("state should be NULL here");
fg_select->state =
gimp_drawable_foreground_extract_siox_init (drawable,
x1, y1, x2 - x1, y2 - y1);
}
gimp_foreground_select_tool_set_mask (fg_select, gdisp, mask);
......@@ -799,6 +818,10 @@ gimp_foreground_select_tool_push_stroke (GimpForegroundSelectTool *fg_select,
fg_select->stroke = NULL;
fg_select->strokes = g_list_append (fg_select->strokes, stroke);
fg_select->refinement |= (stroke->background ?
SIOX_REFINEMENT_ADD_BACKGROUND :
SIOX_REFINEMENT_ADD_FOREGROUND);
}
static gboolean
......@@ -819,20 +842,34 @@ gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
GParamSpec *pspec,
GimpForegroundSelectTool *fg_select)
{
SioxRefinementType refinement = 0;
if (! fg_select->mask)
return;
if (pspec->name &&
(strcmp (pspec->name, "smoothness") == 0 ||
strcmp (pspec->name, "multiblob") == 0 ||
strncmp (pspec->name, "sensitivity", strlen ("sensitivity")) == 0))
if (strcmp (pspec->name, "smoothness") == 0)
{
if (fg_select->idle_id)
g_source_remove (fg_select->idle_id);
fg_select->idle_id =
g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) gimp_foreground_select_tool_idle_select,
fg_select, NULL);
refinement = SIOX_REFINEMENT_CHANGE_SMOOTHNESS;
}
else if (strcmp (pspec->name, "multiblob") == 0)
{
refinement = SIOX_REFINEMENT_CHANGE_MULTIBLOB;
}
else if (strncmp (pspec->name, "sensitivity", strlen ("sensitivity")) == 0)
{
refinement = SIOX_REFINEMENT_CHANGE_SENSITIVITY;
}
if (! refinement)
return;
fg_select->refinement |= refinement;
if (fg_select->idle_id)
g_source_remove (fg_select->idle_id);
fg_select->idle_id =
g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) gimp_foreground_select_tool_idle_select,
fg_select, NULL);
}
......@@ -42,6 +42,8 @@ struct _GimpForegroundSelectTool
GArray *stroke;
GList *strokes;
GimpChannel *mask;
SioxState *state;
SioxRefinementType refinement;
};
struct _GimpForegroundSelectToolClass
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment