[gegl] alpha-inpaint: fixed non integer sampling, and tidy properties
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] alpha-inpaint: fixed non integer sampling, and tidy properties
- Date: Wed, 3 Jul 2019 14:01:04 +0000 (UTC)
commit 81c5ba43dad274f98b07e2f08f41a5dedb3a8693
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Jul 3 15:29:15 2019 +0200
alpha-inpaint: fixed non integer sampling, and tidy properties
Remove some properties that are becoming unneeded with changes in internals.
operations/workshop/inpaint.c | 87 +++++------------------------------
operations/workshop/pixel-duster.h | 92 ++++----------------------------------
2 files changed, 20 insertions(+), 159 deletions(-)
---
diff --git a/operations/workshop/inpaint.c b/operations/workshop/inpaint.c
index a9307d5d9..2492dc060 100644
--- a/operations/workshop/inpaint.c
+++ b/operations/workshop/inpaint.c
@@ -30,16 +30,13 @@
property_int (seek_distance, "seek radius", 5)
value_range (1, 512)
-property_int (min_neigh, "min neigh", 3)
- value_range (0, 4)
-
property_int (min_iter, "min iter", 100)
value_range (1, 512)
property_int (max_iter, "max iter", 2000)
value_range (1, 40000)
-property_int (improvement_iters, "improvement iters", 2)
+property_int (improvement_iters, "improvement iters", 3)
property_double (chance_try, "try chance", 0.33)
value_range (0.0, 1.0)
@@ -48,34 +45,27 @@ property_double (chance_retry, "retry chance", 1.0)
value_range (0.0, 1.0)
ui_steps (0.01, 0.1)
-property_double (ring_gap, "ring gap", 1.3)
- value_range (0.0, 8.0)
- ui_steps (0.1, 0.2)
-
-property_double (ring_gamma, "ring gamma", 1.4)
- value_range (0.0, 4.0)
- ui_steps (0.1, 0.2)
property_double (ring_twist, "ring twist", 0.0)
value_range (0.0, 1.0)
ui_steps (0.01, 0.2)
-property_double (ring_gap1, "ring gap1", 1.2)
- value_range (0.0, 8.0)
+property_double (ring_gap1, "ring gap1", 1.3)
+ value_range (0.0, 16.0)
ui_steps (0.25, 0.25)
property_double (ring_gap2, "ring gap2", 2.5)
- value_range (0.0, 8.0)
+ value_range (0.0, 16.0)
ui_steps (0.25, 0.25)
-property_double (ring_gap3, "ring gap3", 3.5)
- value_range (0.0, 8.0)
+property_double (ring_gap3, "ring gap3", 3.7)
+ value_range (0.0, 16.0)
ui_steps (0.25, 0.25)
-property_double (ring_gap4, "ring gap4", 4.5)
- value_range (0.0, 8.0)
+property_double (ring_gap4, "ring gap4", 5.5)
+ value_range (0.0, 16.0)
ui_steps (0.25, 0.25)
-property_double (metric_dist_powk, "metric dist powk", 2.0)
+property_double (metric_dist_powk, "metric dist powk", 1.5)
value_range (0.0, 10.0)
ui_steps (0.1, 1.0)
@@ -91,11 +81,6 @@ property_double (metric_cohesion, "metric cohesion", 0.004)
value_range (0.0, 10.0)
ui_steps (0.2, 0.2)
-property_double (scale, "enlarge as well as inpaint 1.0 does nothing", 1.0)
- value_range (0.0, 10.0)
- ui_steps (0.5, 0.5)
-
-
#else
#define GEGL_OP_FILTER
@@ -126,30 +111,6 @@ prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "output", format);
}
-static void scaled_copy (PixelDuster *duster,
- GeglBuffer *in,
- GeglBuffer *out,
- gfloat scale)
-{
- GeglRectangle rect;
- const Babl *format = babl_format ("RGBA float");
- gint x, y;
-
- rect = *gegl_buffer_get_extent (in);
- for (y = 0; y < rect.height; y++)
- for (x = 0; x < rect.width; x++)
- {
- float rgba[4];
- gegl_sampler_get (duster->in_sampler_f, x, y, NULL,
- &rgba[0], 0);
- {
- GeglRectangle r = {x * scale, y * scale, 1, 1};
- gegl_buffer_set (out, &r, 0, format, &rgba[0], 0);
- }
- }
-}
-
-
static gboolean
process (GeglOperation *operation,
GeglBuffer *input,
@@ -162,20 +123,15 @@ process (GeglOperation *operation,
GeglRectangle out_rect = *gegl_buffer_get_extent (output);
PixelDuster *duster = pixel_duster_new (input, input, output, &in_rect, &out_rect,
o->seek_distance,
- o->min_neigh,
o->min_iter,
o->max_iter,
o->chance_try,
o->chance_retry,
- o->scale, // scale_x
- o->scale, // scale_y
o->improvement_iters,
- o->ring_gap,
o->ring_gap1,
o->ring_gap2,
o->ring_gap3,
o->ring_gap4,
- o->ring_gamma,
o->ring_twist,
o->metric_dist_powk,
o->metric_empty_hay_score,
@@ -183,10 +139,7 @@ process (GeglOperation *operation,
o->metric_cohesion/1000.0,
operation);
- if (o->scale > 0.9999 && o->scale < 1.0001)
- gegl_buffer_copy (input, NULL, GEGL_ABYSS_NONE, output, NULL);
- else
- scaled_copy (duster, input, output, o->scale);
+ gegl_buffer_copy (input, NULL, GEGL_ABYSS_NONE, output, NULL);
pixel_duster_add_probes_for_transparent (duster);
@@ -234,23 +187,6 @@ operation_process (GeglOperation *operation,
gegl_operation_context_get_level (context));
}
-static GeglRectangle
-get_bounding_box (GeglOperation *operation)
-{
- GeglProperties *o = GEGL_PROPERTIES (operation);
- GeglRectangle *res = gegl_operation_source_get_bounding_box (operation, "input");
- GeglRectangle result = {0,0,100,100};
- if (res)
- result = *res;
- result.x = 0;
- result.y = 0;
- result.width *= o->scale;
- result.height *= o->scale;
-
- return result;
-}
-
-
static void
gegl_op_class_init (GeglOpClass *klass)
{
@@ -263,11 +199,10 @@ gegl_op_class_init (GeglOpClass *klass)
filter_class->process = process;
operation_class->prepare = prepare;
operation_class->process = operation_process;
- operation_class->get_bounding_box = get_bounding_box;
operation_class->get_required_for_output = get_required_for_output;
operation_class->get_cached_region = get_cached_region;
operation_class->opencl_support = FALSE;
- operation_class->threaded = FALSE;
+ operation_class->threaded = TRUE;
gegl_operation_class_set_keys (operation_class,
"name", "gegl:alpha-inpaint",
diff --git a/operations/workshop/pixel-duster.h b/operations/workshop/pixel-duster.h
index d9e4f52eb..060c87117 100644
--- a/operations/workshop/pixel-duster.h
+++ b/operations/workshop/pixel-duster.h
@@ -51,20 +51,14 @@ typedef struct
GeglSampler *ref_sampler_f;
GeglSampler *out_sampler_f;
int seek_radius;
- int minimum_neighbors;
int minimum_iterations;
int maximum_iterations;
int max_age;
float try_chance;
float retry_chance;
- float scale_x;
- float scale_y;
- float ring_gap;
float ring_gaps[8];
-
- float ring_gamma;
float ring_twist;
float metric_dist_powk;
@@ -85,7 +79,7 @@ typedef struct
} PixelDuster;
-#define RINGS 3 // increments works up to 7-8 with no adver
+#define RINGS 4 // increments works up to 7-8 with no adver
#define RAYS 12 // good values for testing 6 8 10 12 16
#define NEIGHBORHOOD (RINGS*RAYS+1)
@@ -103,7 +97,6 @@ struct _Probe {
int target_x;
int target_y;
Probe *neighbors[8]; // cached from coords and iterating all
- int target_neighbors; // cached computation
int age; // not really needed
float old_score; // should be on stack
float score;
@@ -138,12 +131,8 @@ static void init_order(PixelDuster *duster)
for (int circleno = 1; circleno < RINGS; circleno++)
for (float angleno = 0; angleno < RAYS; angleno++)
{
- float mag;
+ float mag = duster->ring_gaps[circleno];
float x, y;
- if (duster->ring_gaps[circleno] > 0.0)
- mag = duster->ring_gaps[circleno];
- else
- mag = pow(duster->ring_gap * (circleno + 1), duster->ring_gamma);
x = cosf ((angleno / RAYS + duster->ring_twist*circleno) * M_PI * 2) * mag;
y = sinf ((angleno / RAYS + duster->ring_twist*circleno) * M_PI * 2) * mag;
@@ -155,7 +144,7 @@ static void init_order(PixelDuster *duster)
}
}
-static void duster_idx_to_x_y (PixelDuster *duster, int index, int *x, int *y)
+static void duster_idx_to_x_y (PixelDuster *duster, int index, float *x, float *y)
{
*x = duster->order[index][0];
*y = duster->order[index][1];
@@ -168,20 +157,15 @@ static PixelDuster * pixel_duster_new (GeglBuffer *reference,
const GeglRectangle *in_rect,
const GeglRectangle *out_rect,
int seek_radius,
- int minimum_neighbors,
int minimum_iterations,
int maximum_iterations,
float try_chance,
float retry_chance,
- float scale_x,
- float scale_y,
int improvement_iterations,
- float ring_gap,
float ring_gap1,
float ring_gap2,
float ring_gap3,
float ring_gap4,
- float ring_gamma,
float ring_twist,
float metric_dist_powk,
float metric_empty_hay_score,
@@ -195,7 +179,6 @@ static PixelDuster * pixel_duster_new (GeglBuffer *reference,
ret->input = input;
ret->output = output;
ret->seek_radius = seek_radius;
- ret->minimum_neighbors = minimum_neighbors;
ret->minimum_iterations = minimum_iterations;
ret->maximum_iterations = maximum_iterations;
ret->try_chance = try_chance;
@@ -210,14 +193,10 @@ static PixelDuster * pixel_duster_new (GeglBuffer *reference,
ret->min_x = 10000;
ret->min_y = 10000;
ret->max_age = improvement_iterations;
- ret->ring_gap = ring_gap;
- ret->ring_gamma = ring_gamma;
ret->ring_twist = ring_twist;
ret->in_rect = *in_rect;
ret->out_rect = *out_rect;
- ret->scale_x = scale_x;
- ret->scale_y = scale_y;
ret->metric_dist_powk = metric_dist_powk;
ret->metric_empty_hay_score = metric_empty_hay_score;
ret->metric_empty_needle_score = metric_empty_needle_score;
@@ -296,7 +275,7 @@ static void extract_site (PixelDuster *duster, GeglBuffer *buffer, double x, dou
for (int i = 0; i < NEIGHBORHOOD; i++)
{
- int dx, dy;
+ float dx, dy;
duster_idx_to_x_y (duster, i, &dx, &dy);
gegl_sampler_get (sampler_f, x + dx * scale, y + dy * scale, NULL, &dst[i*4], 0);
}
@@ -436,70 +415,19 @@ add_probe (PixelDuster *duster, int target_x, int target_y)
probe->target_x = target_x;
probe->target_y = target_y;
- probe->source_x = target_x / duster->scale_x;
- probe->source_y = target_y / duster->scale_y;
+ probe->source_x = target_x;
+ probe->source_y = target_y;
probe->score = INITIAL_SCORE;
g_hash_table_insert (duster->probes_ht,
xy2offset(target_x, target_y), probe);
return probe;
}
-static int
-probe_rel_is_set (PixelDuster *duster, GeglBuffer *output, Probe *probe, int rel_x, int rel_y)
-{
-#if 1
- static const Babl *format = NULL;
- guchar pix[4];
- if (!format) format = babl_format ("R'G'B'A u8");
- gegl_buffer_sample (output, probe->target_x + rel_x, probe->target_y + rel_y, NULL, &pix[0], format,
GEGL_SAMPLER_NEAREST, 0);
- return pix[3] > 5;
-#else
- Probe *neighbor_probe = g_hash_table_lookup (duster->probes_ht,
- xy2offset(probe->target_x + rel_x, probe->target_y + rel_y));
- if (!neighbor_probe || neighbor_probe->age)
- return 1;
- return 0;
-#endif
-}
-
static inline void probe_push (PixelDuster *duster, Probe *probe)
{
}
-#define ret_if_good if (found >=min) goto ret;
-
-static int
-probe_neighbors (PixelDuster *duster, GeglBuffer *output, Probe *probe, int min)
-{
- int found = 0;
- found = probe->target_neighbors;
-
- ret_if_good
-
- found = 0;
-
- if (probe_rel_is_set (duster, output, probe, -1, 0)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, 1, 0)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, 0, 1)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, 0, -1)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, 1, 1)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, -1,-1)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, 1,-1)) found ++;
- ret_if_good
- if (probe_rel_is_set (duster, output, probe, -1, 1)) found ++;
-
-ret:
- probe->target_neighbors = found;
- return found;
-}
-
static gfloat *ensure_hay (PixelDuster *duster, int x, int y)
{
gfloat *hay = NULL;
@@ -806,9 +734,7 @@ static inline void pixel_duster_fill (PixelDuster *duster)
if (probe->score == INITIAL_SCORE || try_replace)
{
- if ((rand()%100)/100.0 < duster->try_chance &&
- probe_neighbors (duster, duster->output, probe, duster->minimum_neighbors) >=
- duster->minimum_neighbors)
+ if ((rand()%100)/100.0 < duster->try_chance)
{
probe_improve (duster, probe);
}
@@ -816,9 +742,9 @@ static inline void pixel_duster_fill (PixelDuster *duster)
}
if (duster->op)
- gegl_operation_progress (duster->op, 0.2 + (total-missing) * 0.8 / total,
+ gegl_operation_progress (duster->op, (total-missing) * 1.0 / total,
"finding suitable pixels");
-#if 1
+#if 0
fprintf (stderr, "\r%i/%i %2.2f run#:%i ", total-missing, total, (total-missing) * 100.0 / total, runs);
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]