app: revive gimpdrawable-foreground-extract

Move the extraction graph from the foreground select tool there.
Enable the PDB wrapper again, using default values for now.
Some sytle cleanup in the foreground select tool.
This commit is contained in:
Michael Natterer 2014-06-03 23:05:23 +02:00
parent bcdf1a3171
commit e2628b9bd0
9 changed files with 215 additions and 293 deletions

View File

@ -324,6 +324,35 @@ gimp_layer_mode_effects_get_type (void)
return type;
}
GType
gimp_matting_engine_get_type (void)
{
static const GEnumValue values[] =
{
{ GIMP_MATTING_ENGINE_GLOBAL, "GIMP_MATTING_ENGINE_GLOBAL", "global" },
{ GIMP_MATTING_ENGINE_LEVIN, "GIMP_MATTING_ENGINE_LEVIN", "levin" },
{ 0, NULL, NULL }
};
static const GimpEnumDesc descs[] =
{
{ GIMP_MATTING_ENGINE_GLOBAL, NC_("matting-engine", "Matting Global"), NULL },
{ GIMP_MATTING_ENGINE_LEVIN, NC_("matting-engine", "Matting Levin"), NULL },
{ 0, NULL, NULL }
};
static GType type = 0;
if (G_UNLIKELY (! type))
{
type = g_enum_register_static ("GimpMattingEngine", values);
gimp_type_set_translation_context (type, "matting-engine");
gimp_enum_set_value_descriptions (type, descs);
}
return type;
}
GType
gimp_alignment_type_get_type (void)
{

View File

@ -168,6 +168,17 @@ typedef enum
} GimpLayerModeEffects;
#define GIMP_TYPE_MATTING_ENGINE (gimp_matting_engine_get_type ())
GType gimp_matting_engine_get_type (void) G_GNUC_CONST;
typedef enum /*< pdb-skip >*/
{
GIMP_MATTING_ENGINE_GLOBAL, /*< desc="Matting Global" >*/
GIMP_MATTING_ENGINE_LEVIN, /*< desc="Matting Levin" >*/
} GimpMattingEngine;
#define GIMP_TYPE_ALIGNMENT_TYPE (gimp_alignment_type_get_type ())
GType gimp_alignment_type_get_type (void) G_GNUC_CONST;

View File

@ -15,19 +15,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#include "config.h"
#include <gio/gio.h>
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "base/siox.h"
#include "base/tile-manager.h"
#include "gegl/gimp-gegl-utils.h"
#include "gimpchannel.h"
@ -41,137 +38,88 @@
/* public functions */
void
gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpForegroundExtractMode mode,
GimpDrawable *mask,
GimpProgress *progress)
GeglBuffer *
gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpMattingEngine engine,
gint global_iterations,
gint levin_levels,
gint levin_active_levels,
GeglBuffer *trimap,
GimpProgress *progress)
{
SioxState *state;
const gdouble sensitivity[3] = { SIOX_DEFAULT_SENSITIVITY_L,
SIOX_DEFAULT_SENSITIVITY_A,
SIOX_DEFAULT_SENSITIVITY_B };
g_return_if_fail (GIMP_IS_DRAWABLE (mask));
g_return_if_fail (mode == GIMP_FOREGROUND_EXTRACT_SIOX);
state =
gimp_drawable_foreground_extract_siox_init (drawable,
0, 0,
gimp_item_get_width (GIMP_ITEM (mask)),
gimp_item_get_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);
}
}
SioxState *
gimp_drawable_foreground_extract_siox_init (GimpDrawable *drawable,
gint x,
gint y,
gint width,
gint height)
{
GeglBuffer *buffer;
const guchar *colormap = NULL;
gboolean intersect;
gint offset_x;
gint offset_y;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
if (gimp_drawable_is_indexed (drawable))
colormap = gimp_drawable_get_colormap (drawable);
gimp_item_get_offset (GIMP_ITEM (drawable), &offset_x, &offset_y);
intersect = gimp_rectangle_intersect (offset_x, offset_y,
gimp_item_get_width (GIMP_ITEM (drawable)),
gimp_item_get_height (GIMP_ITEM (drawable)),
x, y, width, height,
&x, &y, &width, &height);
/* FIXME:
* Clear the mask outside the rectangle that we are working on?
*/
if (! intersect)
return NULL;
buffer = gimp_drawable_get_buffer (drawable);
return siox_init (gimp_gegl_buffer_get_tiles (buffer), 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)
{
GeglBuffer *buffer;
gint x1, y1;
gint x2, y2;
g_return_if_fail (GIMP_IS_DRAWABLE (mask));
g_return_if_fail (babl_format_get_bytes_per_pixel (gimp_drawable_get_format (mask)) == 1);
g_return_if_fail (state != NULL);
GeglBuffer *drawable_buffer;
GeglNode *gegl;
GeglNode *input_node;
GeglNode *trimap_node;
GeglNode *matting_node;
GeglNode *output_node;
GeglBuffer *buffer;
GeglProcessor *processor;
gdouble value;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (GEGL_IS_BUFFER (trimap));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
if (progress)
gimp_progress_start (progress, _("Foreground Extraction"), FALSE);
progress = gimp_progress_start (progress,
_("Computing alpha of unknown pixels"),
FALSE);
if (GIMP_IS_CHANNEL (mask))
drawable_buffer = gimp_drawable_get_buffer (drawable);
gegl = gegl_node_new ();
trimap_node = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", trimap,
NULL);
input_node = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", drawable_buffer,
NULL);
output_node = gegl_node_new_child (gegl,
"operation", "gegl:buffer-sink",
"buffer", &buffer,
"format", NULL,
NULL);
if (engine == GIMP_MATTING_ENGINE_GLOBAL)
{
gimp_channel_bounds (GIMP_CHANNEL (mask), &x1, &y1, &x2, &y2);
matting_node = gegl_node_new_child (gegl,
"operation", "gegl:matting-global",
"iterations", global_iterations,
NULL);
}
else
{
x1 = 0;
y1 = 0;
x2 = gimp_item_get_width (GIMP_ITEM (mask));
y2 = gimp_item_get_height (GIMP_ITEM (mask));
matting_node = gegl_node_new_child (gegl,
"operation", "gegl:matting-levin",
"levels", levin_levels,
"active_levels", levin_active_levels,
NULL);
}
buffer = gimp_drawable_get_buffer (mask);
gegl_node_connect_to (input_node, "output",
matting_node, "input");
gegl_node_connect_to (trimap_node, "output",
matting_node, "aux");
gegl_node_connect_to (matting_node, "output",
output_node, "input");
siox_foreground_extract (state, refinement,
gimp_gegl_buffer_get_tiles (buffer),
x1, y1, x2, y2,
smoothness, sensitivity, multiblob,
(SioxProgressFunc) gimp_progress_set_value,
progress);
processor = gegl_node_new_processor (output_node, NULL);
while (gegl_processor_work (processor, &value))
{
if (progress)
gimp_progress_set_value (progress, value);
}
if (progress)
gimp_progress_end (progress);
gimp_drawable_update (mask, x1, y1, x2, y2);
g_object_unref (processor);
g_object_unref (gegl);
return buffer;
}
void
gimp_drawable_foreground_extract_siox_done (SioxState *state)
{
g_return_if_fail (state != NULL);
siox_done (state);
}
#endif

View File

@ -15,36 +15,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if 0
#ifndef __GIMP_DRAWABLE_FOREGROUND_EXTRACT_H__
#define __GIMP_DRAWABLE_FOREGROUND_EXTRACT_H__
/* 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);
GeglBuffer * gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpMattingEngine engine,
gint global_iterations,
gint levin_levels,
gint levin_active_levels,
GeglBuffer *trimap,
GimpProgress *progress);
#endif /* __GIMP_DRAWABLE_FOREGROUND_EXTRACT_H__ */
#endif

View File

@ -29,6 +29,7 @@
#include "config/gimpcoreconfig.h"
#include "core/gimp.h"
#include "core/gimpchannel-select.h"
#include "core/gimpdrawable-foreground-extract.h"
#include "core/gimpdrawable-offset.h"
#include "core/gimpdrawable-preview.h"
@ -45,6 +46,7 @@
#include "gimppdb.h"
#include "gimppdb-utils.h"
#include "gimppdbcontext.h"
#include "gimpprocedure.h"
#include "internal-procs.h"
@ -938,13 +940,35 @@ drawable_foreground_extract_invoker (GimpProcedure *procedure,
if (success)
{
/*
if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error))
gimp_drawable_foreground_extract (drawable, mode, mask, progress);
if (mode == GIMP_FOREGROUND_EXTRACT_MATTING &&
gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error))
{
GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GeglBuffer *buffer;
buffer = gimp_drawable_foreground_extract (drawable,
GIMP_MATTING_ENGINE_GLOBAL,
2,
2,
2,
gimp_drawable_get_buffer (mask),
progress);
gimp_channel_select_buffer (gimp_image_get_mask (image),
C_("command", "Foreground Select"),
buffer,
0, /* x offset */
0, /* y offset */
GIMP_CHANNEL_OP_REPLACE,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y);
g_object_unref (buffer);
}
else
success = FALSE;
*/
success = FALSE;
}
return gimp_procedure_get_return_values (procedure, success,

View File

@ -745,8 +745,10 @@ gimp_foreground_select_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,
const GParamSpec *pspec)
{
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
GimpForegroundSelectOptions *fg_options = GIMP_FOREGROUND_SELECT_OPTIONS (options);
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
GimpForegroundSelectOptions *fg_options;
fg_options = GIMP_FOREGROUND_SELECT_OPTIONS (options);
if (! tool->display)
return;
@ -754,27 +756,37 @@ gimp_foreground_select_tool_options_notify (GimpTool *tool,
if (! strcmp (pspec->name, "mask-color"))
{
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
gimp_foreground_select_tool_set_trimap (fg_select);
{
gimp_foreground_select_tool_set_trimap (fg_select);
}
else if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
gimp_foreground_select_tool_set_preview (fg_select);
{
gimp_foreground_select_tool_set_preview (fg_select);
}
}
else if (! strcmp (pspec->name, "engine"))
{
if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
gimp_foreground_select_tool_preview (fg_select);
{
gimp_foreground_select_tool_preview (fg_select);
}
}
else if (! strcmp (pspec->name, "iterations"))
{
if (fg_options->engine == GIMP_MATTING_ENGINE_GLOBAL &&
fg_select->state == MATTING_STATE_PREVIEW_MASK)
gimp_foreground_select_tool_preview (fg_select);
{
gimp_foreground_select_tool_preview (fg_select);
}
}
else if (! strcmp (pspec->name, "levels") ||
! strcmp (pspec->name, "active-levels"))
{
if (fg_options->engine == GIMP_MATTING_ENGINE_LEVIN &&
fg_select->state == MATTING_STATE_PREVIEW_MASK)
gimp_foreground_select_tool_preview (fg_select);
{
gimp_foreground_select_tool_preview (fg_select);
}
}
}
@ -802,12 +814,11 @@ gimp_foreground_select_tool_get_area (GeglBuffer *mask,
static void
gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpForegroundSelectTool *fg_select;
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
GimpForegroundSelectOptions *options;
fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
@ -861,16 +872,13 @@ static void
gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
GimpDisplay *display)
{
GimpForegroundSelectTool *fg_select;
GimpImage *image = gimp_display_get_image (display);
GimpDrawable *drawable;
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel);
GimpImage *image = gimp_display_get_image (display);
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
GimpScanConvert *scan_convert;
const GimpVector2 *points;
gint n_points;
drawable = gimp_image_get_active_drawable (image);
fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel);
if (! drawable)
return;
@ -887,10 +895,11 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
points,
TRUE);
fg_select->trimap = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
gimp_image_get_width (image),
gimp_image_get_height (image)),
gimp_image_get_mask_format (image));
fg_select->trimap =
gegl_buffer_new (GEGL_RECTANGLE (0, 0,
gimp_image_get_width (image),
gimp_image_get_height (image)),
gimp_image_get_mask_format (image));
gimp_scan_convert_render_value (scan_convert, fg_select->trimap,
0, 0, 0.5);
@ -1041,20 +1050,11 @@ static void
gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
GimpForegroundSelectOptions *options;
GimpImage *image = gimp_display_get_image (tool->display);
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
GeglBuffer *trimap_buffer;
GeglBuffer *drawable_buffer;
GeglNode *gegl;
GeglNode *matting_node;
GeglNode *input_image;
GeglNode *input_trimap;
GeglNode *output_mask;
GeglBuffer *buffer;
GimpProgress *progress;
GeglProcessor *processor;
gdouble value;
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
if (fg_select->mask)
{
@ -1062,70 +1062,15 @@ gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select)
fg_select->mask = NULL;
}
progress = gimp_progress_start (GIMP_PROGRESS (fg_select),
_("Computing alpha of unknown pixels"),
FALSE);
trimap_buffer = fg_select->trimap;
drawable_buffer = gimp_drawable_get_buffer (drawable);
gegl = gegl_node_new ();
input_trimap = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", trimap_buffer,
NULL);
input_image = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", drawable_buffer,
NULL);
output_mask = gegl_node_new_child (gegl,
"operation", "gegl:buffer-sink",
"buffer", &buffer,
"format", NULL,
NULL);
if (options->engine == GIMP_MATTING_ENGINE_GLOBAL)
{
matting_node = gegl_node_new_child (gegl,
"operation", "gegl:matting-global",
"iterations", options->iterations,
NULL);
}
else
{
matting_node = gegl_node_new_child (gegl,
"operation", "gegl:matting-levin",
"levels", options->levels,
"active_levels", options->active_levels,
NULL);
}
gegl_node_connect_to (input_image, "output",
matting_node, "input");
gegl_node_connect_to (input_trimap, "output",
matting_node, "aux");
gegl_node_connect_to (matting_node, "output",
output_mask, "input");
processor = gegl_node_new_processor (output_mask, NULL);
while (gegl_processor_work (processor, &value))
{
if (progress)
gimp_progress_set_value (progress, value);
}
if (progress)
gimp_progress_end (progress);
g_object_unref (processor);
fg_select->mask = buffer;
fg_select->mask = gimp_drawable_foreground_extract (drawable,
options->engine,
options->iterations,
options->levels,
options->active_levels,
fg_select->trimap,
GIMP_PROGRESS (fg_select));
gimp_foreground_select_tool_set_preview (fg_select);
g_object_unref (gegl);
}
static void

View File

@ -323,35 +323,6 @@ gimp_matting_draw_mode_get_type (void)
return type;
}
GType
gimp_matting_engine_get_type (void)
{
static const GEnumValue values[] =
{
{ GIMP_MATTING_ENGINE_GLOBAL, "GIMP_MATTING_ENGINE_GLOBAL", "global" },
{ GIMP_MATTING_ENGINE_LEVIN, "GIMP_MATTING_ENGINE_LEVIN", "levin" },
{ 0, NULL, NULL }
};
static const GimpEnumDesc descs[] =
{
{ GIMP_MATTING_ENGINE_GLOBAL, NC_("matting-engine", "Matting Global"), NULL },
{ GIMP_MATTING_ENGINE_LEVIN, NC_("matting-engine", "Matting Levin"), NULL },
{ 0, NULL, NULL }
};
static GType type = 0;
if (G_UNLIKELY (! type))
{
type = g_enum_register_static ("GimpMattingEngine", values);
gimp_type_set_translation_context (type, "matting-engine");
gimp_enum_set_value_descriptions (type, descs);
}
return type;
}
GType
gimp_warp_behavior_get_type (void)
{

View File

@ -144,17 +144,6 @@ typedef enum
} GimpMattingDrawMode;
#define GIMP_TYPE_MATTING_ENGINE (gimp_matting_engine_get_type ())
GType gimp_matting_engine_get_type (void) G_GNUC_CONST;
typedef enum
{
GIMP_MATTING_ENGINE_GLOBAL, /*< desc="Matting Global" >*/
GIMP_MATTING_ENGINE_LEVIN, /*< desc="Matting Levin" >*/
} GimpMattingEngine;
#define GIMP_TYPE_WARP_BEHAVIOR (gimp_warp_behavior_get_type ())
GType gimp_warp_behavior_get_type (void) G_GNUC_CONST;

View File

@ -952,13 +952,35 @@ HELP
headers => [ qw("core/gimpdrawable-foreground-extract.h") ],
code => <<'CODE'
{
/*
if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error))
gimp_drawable_foreground_extract (drawable, mode, mask, progress);
if (mode == GIMP_FOREGROUND_EXTRACT_MATTING &&
gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error))
{
GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GeglBuffer *buffer;
buffer = gimp_drawable_foreground_extract (drawable,
GIMP_MATTING_ENGINE_GLOBAL,
2,
2,
2,
gimp_drawable_get_buffer (mask),
progress);
gimp_channel_select_buffer (gimp_image_get_mask (image),
C_("command", "Foreground Select"),
buffer,
0, /* x offset */
0, /* y offset */
GIMP_CHANNEL_OP_REPLACE,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y);
g_object_unref (buffer);
}
else
success = FALSE;
*/
success = FALSE;
}
CODE
);
@ -969,9 +991,11 @@ CODE
"gegl/gimp-babl.h"
"gegl/gimp-babl-compat.h"
"core/gimp.h"
"core/gimpchannel-select.h"
"core/gimpdrawable-offset.h"
"core/gimptempbuf.h"
"gimppdb-utils.h"
"gimppdbcontext.h"
"gimp-intl.h");
@procs = qw(drawable_get_format