Commit c57b4f0f authored by Michael Natterer's avatar Michael Natterer 😴

app: port by color select and fuzzy select to float

so it works nicely on all precisions, disable HSV color matching for
now, need to decide what to do with it.
parent 9e73e7eb
......@@ -459,7 +459,7 @@ gimp_channel_select_fuzzy (GimpChannel *channel,
gboolean sample_merged,
gint x,
gint y,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
GimpChannelOps op,
......@@ -505,7 +505,7 @@ gimp_channel_select_by_color (GimpChannel *channel,
GimpDrawable *drawable,
gboolean sample_merged,
const GimpRGB *color,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
GimpChannelOps op,
......
......@@ -118,7 +118,7 @@ void gimp_channel_select_fuzzy (GimpChannel *channel,
gboolean sample_merged,
gint x,
gint y,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
GimpChannelOps op,
......@@ -130,7 +130,7 @@ void gimp_channel_select_by_color (GimpChannel *channel,
GimpDrawable *drawable,
gboolean sample_merged,
const GimpRGB *color,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
GimpChannelOps op,
......
......@@ -168,7 +168,7 @@ gimp_drawable_bucket_fill_internal (GimpDrawable *drawable,
mask = gimp_image_contiguous_region_by_seed (image, drawable,
sample_merged,
TRUE,
(gint) threshold,
threshold,
fill_transparent,
fill_criterion,
(gint) x,
......
......@@ -23,9 +23,12 @@
#include <gegl.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "core-types.h"
#include "gegl/gimp-babl.h"
#include "gimpchannel.h"
#include "gimpimage.h"
#include "gimpimage-contiguous-region.h"
......@@ -34,25 +37,25 @@
/* local function prototypes */
static gint pixel_difference (const guchar *col1,
const guchar *col2,
static gfloat pixel_difference (const gfloat *col1,
const gfloat *col2,
gboolean antialias,
gint threshold,
gint bytes,
gfloat threshold,
gint n_components,
gboolean has_alpha,
gboolean select_transparent,
GimpSelectCriterion select_criterion);
static gboolean find_contiguous_segment (const guchar *col,
static gboolean find_contiguous_segment (const gfloat *col,
GeglBuffer *src_buffer,
GeglBuffer *mask_buffer,
const Babl *src_format,
gint bytes,
gint n_components,
gboolean has_alpha,
gint width,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
gboolean antialias,
gint threshold,
gfloat threshold,
gint initial_x,
gint initial_y,
gint *start,
......@@ -63,10 +66,10 @@ static void find_contiguous_region_helper (GeglBuffer *src_buffer,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
gboolean antialias,
gint threshold,
gfloat threshold,
gint x,
gint y,
const guchar *col);
const gfloat *col);
/* public functions */
......@@ -76,7 +79,7 @@ gimp_image_contiguous_region_by_seed (GimpImage *image,
GimpDrawable *drawable,
gboolean sample_merged,
gboolean antialias,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
gint x,
......@@ -87,7 +90,7 @@ gimp_image_contiguous_region_by_seed (GimpImage *image,
GimpChannel *mask;
GeglBuffer *mask_buffer;
const Babl *src_format;
guchar start_col[MAX_CHANNELS];
gfloat start_col[MAX_CHANNELS];
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
......@@ -101,7 +104,11 @@ gimp_image_contiguous_region_by_seed (GimpImage *image,
src_format = gimp_pickable_get_format (pickable);
if (babl_format_is_palette (src_format))
src_format = babl_format ("R'G'B'A u8");
src_format = babl_format ("RGBA float");
else
src_format = gimp_babl_format (gimp_babl_format_get_base_type (src_format),
GIMP_PRECISION_FLOAT,
babl_format_has_alpha (src_format));
src_buffer = gimp_pickable_get_buffer (pickable);
......@@ -118,12 +125,12 @@ gimp_image_contiguous_region_by_seed (GimpImage *image,
{
if (select_transparent)
{
gint bytes = babl_format_get_bytes_per_pixel (src_format);
gint n_components = babl_format_get_n_components (src_format);
/* don't select transparent regions if the start pixel isn't
* fully transparent
*/
if (start_col[bytes - 1] > 0)
if (start_col[n_components - 1] > 0)
select_transparent = FALSE;
}
}
......@@ -145,7 +152,7 @@ gimp_image_contiguous_region_by_color (GimpImage *image,
GimpDrawable *drawable,
gboolean sample_merged,
gboolean antialias,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
const GimpRGB *color)
......@@ -163,13 +170,13 @@ gimp_image_contiguous_region_by_color (GimpImage *image,
GeglBuffer *mask_buffer;
gint width, height;
gboolean has_alpha;
guchar col[MAX_CHANNELS];
gfloat col[MAX_CHANNELS];
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail (color != NULL, NULL);
gimp_rgba_get_uchar (color, &col[0], &col[1], &col[2], &col[3]);
gimp_rgba_get_pixel (color, babl_format ("RGBA float"), col);
if (sample_merged)
pickable = GIMP_PICKABLE (gimp_image_get_projection (image));
......@@ -185,7 +192,7 @@ gimp_image_contiguous_region_by_color (GimpImage *image,
height = gegl_buffer_get_height (src_buffer);
iter = gegl_buffer_iterator_new (src_buffer,
NULL, 0, babl_format ("R'G'B'A u8"),
NULL, 0, babl_format ("RGBA float"),
GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
if (has_alpha)
......@@ -194,7 +201,7 @@ gimp_image_contiguous_region_by_color (GimpImage *image,
{
/* don't select transparancy if "color" isn't fully transparent
*/
if (col[3] > 0)
if (col[3] > 0.0)
select_transparent = FALSE;
}
}
......@@ -208,13 +215,13 @@ gimp_image_contiguous_region_by_color (GimpImage *image,
mask_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
gegl_buffer_iterator_add (iter, mask_buffer,
NULL, 0, babl_format ("Y u8"),
NULL, 0, babl_format ("Y float"),
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
while (gegl_buffer_iterator_next (iter))
{
const guchar *src = iter->data[0];
guchar *dest = iter->data[1];
const gfloat *src = iter->data[0];
gfloat *dest = iter->data[1];
while (iter->length--)
{
......@@ -238,59 +245,58 @@ gimp_image_contiguous_region_by_color (GimpImage *image,
/* private functions */
static gint
pixel_difference (const guchar *col1,
const guchar *col2,
static gfloat
pixel_difference (const gfloat *col1,
const gfloat *col2,
gboolean antialias,
gint threshold,
gint bytes,
gfloat threshold,
gint n_components,
gboolean has_alpha,
gboolean select_transparent,
GimpSelectCriterion select_criterion)
{
gint max = 0;
gfloat max = 0.0;
/* if there is an alpha channel, never select transparent regions */
if (! select_transparent && has_alpha && col2[bytes - 1] == 0)
return 0;
if (! select_transparent && has_alpha && col2[n_components - 1] == 0.0)
return 0.0;
if (select_transparent && has_alpha)
{
max = abs (col1[bytes - 1] - col2[bytes - 1]);
max = fabs (col1[n_components - 1] - col2[n_components - 1]);
}
else
{
gint diff;
gfloat diff;
gint b;
gint av0, av1, av2;
gint bv0, bv1, bv2;
if (has_alpha)
bytes--;
n_components--;
switch (select_criterion)
{
case GIMP_SELECT_CRITERION_COMPOSITE:
for (b = 0; b < bytes; b++)
for (b = 0; b < n_components; b++)
{
diff = abs (col1[b] - col2[b]);
diff = fabs (col1[b] - col2[b]);
if (diff > max)
max = diff;
}
break;
case GIMP_SELECT_CRITERION_R:
max = abs (col1[0] - col2[0]);
max = fabs (col1[0] - col2[0]);
break;
case GIMP_SELECT_CRITERION_G:
max = abs (col1[1] - col2[1]);
max = fabs (col1[1] - col2[1]);
break;
case GIMP_SELECT_CRITERION_B:
max = abs (col1[2] - col2[2]);
max = fabs (col1[2] - col2[2]);
break;
#if 0
case GIMP_SELECT_CRITERION_H:
av0 = (gint) col1[0];
av1 = (gint) col1[1];
......@@ -334,55 +340,56 @@ pixel_difference (const guchar *col1,
gimp_rgb_to_hsv_int (&bv0, &bv1, &bv2);
max = abs (av2 - bv2);
break;
#endif
}
}
if (antialias && threshold > 0)
if (antialias && threshold > 0.0)
{
gfloat aa = 1.5 - ((gfloat) max / threshold);
gfloat aa = 1.5 - (max / threshold);
if (aa <= 0.0)
return 0;
return 0.0;
else if (aa < 0.5)
return (guchar) (aa * 512);
return aa * 2.0;
else
return 255;
return 1.0;
}
else
{
if (max > threshold)
return 0;
return 0.0;
else
return 255;
return 1.0;
}
}
static gboolean
find_contiguous_segment (const guchar *col,
find_contiguous_segment (const gfloat *col,
GeglBuffer *src_buffer,
GeglBuffer *mask_buffer,
const Babl *src_format,
gint bytes,
gint n_components,
gboolean has_alpha,
gint width,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
gboolean antialias,
gint threshold,
gfloat threshold,
gint initial_x,
gint initial_y,
gint *start,
gint *end)
{
guchar s[MAX_CHANNELS];
guchar mask_row[width];
guchar diff;
gfloat s[MAX_CHANNELS];
gfloat mask_row[width];
gfloat diff;
gegl_buffer_sample (src_buffer, initial_x, initial_y, NULL, s, src_format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
diff = pixel_difference (col, s, antialias, threshold,
bytes, has_alpha, select_transparent,
n_components, has_alpha, select_transparent,
select_criterion);
/* check the starting pixel */
......@@ -399,7 +406,7 @@ find_contiguous_segment (const guchar *col,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
diff = pixel_difference (col, s, antialias, threshold,
bytes, has_alpha, select_transparent,
n_components, has_alpha, select_transparent,
select_criterion);
mask_row[*start] = diff;
......@@ -417,7 +424,7 @@ find_contiguous_segment (const guchar *col,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
diff = pixel_difference (col, s, antialias, threshold,
bytes, has_alpha, select_transparent,
n_components, has_alpha, select_transparent,
select_criterion);
mask_row[*end] = diff;
......@@ -428,7 +435,7 @@ find_contiguous_segment (const guchar *col,
gegl_buffer_set (mask_buffer, GEGL_RECTANGLE (*start, initial_y,
*end - *start, 1),
0, babl_format ("Y u8"), &mask_row[*start],
0, babl_format ("Y float"), &mask_row[*start],
GEGL_AUTO_ROWSTRIDE);
/* XXX this should now be needed and is a performance killer */
......@@ -444,14 +451,13 @@ find_contiguous_region_helper (GeglBuffer *src_buffer,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
gboolean antialias,
gint threshold,
gfloat threshold,
gint x,
gint y,
const guchar *col)
const gfloat *col)
{
gint start, end;
gint new_start, new_end;
guchar val;
GQueue *coord_stack;
coord_stack = g_queue_new ();
......@@ -473,15 +479,17 @@ find_contiguous_region_helper (GeglBuffer *src_buffer,
for (x = start + 1; x < end; x++)
{
gfloat val;
gegl_buffer_sample (mask_buffer, x, y, NULL, &val,
babl_format ("Y u8"),
babl_format ("Y float"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
if (val != 0)
if (val != 0.0)
continue;
if (! find_contiguous_segment (col, src_buffer, mask_buffer,
format,
babl_format_get_bytes_per_pixel (format),
babl_format_get_n_components (format),
babl_format_has_alpha (format),
gegl_buffer_get_width (src_buffer),
select_transparent, select_criterion,
......
......@@ -23,7 +23,7 @@ GimpChannel * gimp_image_contiguous_region_by_seed (GimpImage *image,
GimpDrawable *drawable,
gboolean sample_merged,
gboolean antialias,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
gint x,
......@@ -33,7 +33,7 @@ GimpChannel * gimp_image_contiguous_region_by_color (GimpImage *image,
GimpDrawable *drawable,
gboolean sample_merged,
gboolean antialias,
gint threshold,
gfloat threshold,
gboolean select_transparent,
GimpSelectCriterion select_criterion,
const GimpRGB *color);
......
......@@ -607,7 +607,8 @@ edit_bucket_fill_invoker (GimpProcedure *procedure,
paint_mode, opacity / 100.0,
FALSE /* don't fill transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
threshold, sample_merged, x, y,
threshold / 255.0,
sample_merged, x, y,
error);
}
}
......@@ -677,7 +678,8 @@ edit_bucket_fill_full_invoker (GimpProcedure *procedure,
paint_mode, opacity / 100.0,
fill_transparent,
select_criterion,
threshold, sample_merged, x, y,
threshold / 255.0,
sample_merged, x, y,
error);
}
}
......
......@@ -72,7 +72,7 @@ image_select_color_invoker (GimpProcedure *procedure,
gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
pdb_context->sample_merged,
&color,
(gint) (pdb_context->sample_threshold * 255.99),
pdb_context->sample_threshold,
pdb_context->sample_transparent,
pdb_context->sample_criterion,
operation,
......@@ -122,7 +122,7 @@ image_select_contiguous_color_invoker (GimpProcedure *procedure,
drawable,
pdb_context->sample_merged,
x, y,
(gint) (pdb_context->sample_threshold * 255.99),
pdb_context->sample_threshold,
pdb_context->sample_transparent,
pdb_context->sample_criterion,
operation,
......
......@@ -74,7 +74,7 @@ by_color_select_invoker (GimpProcedure *procedure,
gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
sample_merged,
&color,
threshold,
threshold / 255.0,
FALSE /* don't select transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
operation,
......@@ -128,7 +128,7 @@ by_color_select_full_invoker (GimpProcedure *procedure,
gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
sample_merged,
&color,
threshold,
threshold / 255.0,
select_transparent,
select_criterion,
operation,
......@@ -268,7 +268,7 @@ fuzzy_select_invoker (GimpProcedure *procedure,
drawable,
sample_merged,
x, y,
threshold,
threshold / 255.0,
FALSE /* don't select transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
operation,
......@@ -325,7 +325,7 @@ fuzzy_select_full_invoker (GimpProcedure *procedure,
drawable,
sample_merged,
x, y,
threshold,
threshold / 255.0,
select_transparent,
select_criterion,
operation,
......
......@@ -215,7 +215,7 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
gimp_context_get_opacity (context),
options->fill_transparent,
options->fill_criterion,
options->threshold,
options->threshold / 255.0,
options->sample_merged,
x, y, &error))
{
......
......@@ -129,7 +129,7 @@ gimp_by_color_select_tool_get_mask (GimpRegionSelectTool *region_select,
return gimp_image_contiguous_region_by_color (image, drawable,
options->sample_merged,
sel_options->antialias,
options->threshold,
options->threshold / 255.0,
options->select_transparent,
options->select_criterion,
&color);
......
......@@ -117,7 +117,7 @@ gimp_fuzzy_select_tool_get_mask (GimpRegionSelectTool *region_select,
return gimp_image_contiguous_region_by_seed (image, drawable,
options->sample_merged,
sel_options->antialias,
options->threshold,
options->threshold / 255.0,
options->select_transparent,
options->select_criterion,
x, y);
......
......@@ -651,7 +651,8 @@ HELP
paint_mode, opacity / 100.0,
FALSE /* don't fill transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
threshold, sample_merged, x, y,
threshold / 255.0,
sample_merged, x, y,
error);
}
}
......@@ -749,7 +750,8 @@ HELP
paint_mode, opacity / 100.0,
fill_transparent,
select_criterion,
threshold, sample_merged, x, y,
threshold / 255.0,
sample_merged, x, y,
error);
}
}
......
......@@ -64,7 +64,7 @@ HELP
gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
pdb_context->sample_merged,
&color,
(gint) (pdb_context->sample_threshold * 255.99),
pdb_context->sample_threshold,
pdb_context->sample_transparent,
pdb_context->sample_criterion,
operation,
......@@ -140,7 +140,7 @@ HELP
drawable,
pdb_context->sample_merged,
x, y,
(gint) (pdb_context->sample_threshold * 255.99),
pdb_context->sample_threshold,
pdb_context->sample_transparent,
pdb_context->sample_criterion,
operation,
......
......@@ -46,7 +46,7 @@ sub by_color_select {
gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
sample_merged,
&color,
threshold,
threshold / 255.0,
FALSE /* don't select transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
operation,
......@@ -101,7 +101,7 @@ sub by_color_select_full {
gimp_channel_select_by_color (gimp_image_get_mask (image), drawable,
sample_merged,
&color,
threshold,
threshold / 255.0,
select_transparent,
select_criterion,
operation,
......@@ -233,7 +233,7 @@ sub fuzzy_select {
drawable,
sample_merged,
x, y,
threshold,
threshold / 255.0,
FALSE /* don't select transparent */,
GIMP_SELECT_CRITERION_COMPOSITE,
operation,
......@@ -293,7 +293,7 @@ sub fuzzy_select_full {
drawable,
sample_merged,
x, y,
threshold,
threshold / 255.0,
select_transparent,
select_criterion,
operation,
......
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