[gegl] pixel-duster: split corpus database is 4096 hashtables
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] pixel-duster: split corpus database is 4096 hashtables
- Date: Sun, 25 Feb 2018 13:19:26 +0000 (UTC)
commit 83ec99013151d2fb78204ae31882ea7fb9f195b3
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Feb 21 01:42:44 2018 +0100
pixel-duster: split corpus database is 4096 hashtables
Decide which hash-table corpus samples go into by a 4bit per pixel start
fragment, when computing a relevant subsetting index for which hashtable to use
- include neighbouring "bins" per pixel in neighborhood, as well as full
variation for that part of index if needle contains transparency.
The result is a quality near exhaustive search; at orders of magnitude better
performance.
operations/workshop/enlarge.c | 176 ++++++++--------------
operations/workshop/inpaint.c | 14 +-
operations/workshop/pixel-duster.h | 302 ++++++++++++++++++++++++++----------
3 files changed, 288 insertions(+), 204 deletions(-)
---
diff --git a/operations/workshop/enlarge.c b/operations/workshop/enlarge.c
index 6a2aecc..f8a3f89 100644
--- a/operations/workshop/enlarge.c
+++ b/operations/workshop/enlarge.c
@@ -25,22 +25,10 @@
/* most of these should go away - here for ease of algorithm experimentation */
-property_int (seek_distance, "seek radius", 8)
+property_int (seek_distance, "seek radius", 48)
value_range (4, 512)
-property_int (min_neigh, "min neigh", 1)
- value_range (1, 10)
-
-property_int (min_iter, "min iter", 3)
- value_range (1, 512)
-
-property_double (chance_try, "try chance", 1.0)
- value_range (0.0, 1.0)
-
-property_double (chance_retry, "retry chance", 0.33)
- value_range (0.0, 1.0)
-
-property_double (scale, "scale", 4.0)
+property_double (scale, "scale", 2.0)
value_range (0.01, 16.0)
#else
@@ -75,9 +63,7 @@ prepare (GeglOperation *operation)
static void scaled_copy (GeglBuffer *in,
GeglBuffer *out,
- gfloat scale,
- int mask_blank,
- int mask_set)
+ gfloat scale)
{
GeglRectangle rect;
const Babl *format = babl_format ("RGBA float");
@@ -87,23 +73,61 @@ static void scaled_copy (GeglBuffer *in,
for (y = 0; y < rect.height; y++)
for (x = 0; x < rect.width; x++)
{
+ float rgba[4];
GeglRectangle r = {x, y, 1, 1};
- gfloat rgba[4] = {0.0, 0.0, 0.0, 0.0};
- int bit = 1<< ((y%2)*2+(x%2));
- if (mask_blank & bit)
- {
- gegl_buffer_set (out, &r, 0, format, &rgba[0], 0);
- }
- else if (mask_set & bit)
- {
- gegl_buffer_sample (in, x / scale, y / scale, NULL,
- &rgba[0], format,
- GEGL_SAMPLER_NOHALO, 0);
- gegl_buffer_set (out, &r, 0, format, &rgba[0], 0);
- }
+ gegl_buffer_sample (in, x / scale, y / scale, NULL,
+ &rgba[0], format,
+ GEGL_SAMPLER_NOHALO, 0);
+ gegl_buffer_set (out, &r, 0, format, &rgba[0], 0);
}
}
+
+static void improve (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 (out);
+ for (y = 0; y < rect.height; y++)
+ {
+ int xstart = 0;
+ int xinc = 1;
+ int xend = rect.width;
+#if 0 /* consistent scanline direction produces more consistent results */
+ if (y%2)
+ {
+ xstart = rect.width - 1;
+ xinc = -1;
+ xend = -1;
+ }
+#endif
+ for (x = xstart; x != xend; x+=xinc)
+ {
+ Probe *probe;
+ probe = add_probe (duster, x, y);
+#if 1
+ if (probe_improve (duster, probe) == 0)
+ {
+ gfloat rgba[4];
+ gegl_buffer_sample (duster->input, probe->source_x, probe->source_y, NULL, &rgba[0], format,
GEGL_SAMPLER_NEAREST, 0);
+ if (rgba[3] <= 0.01)
+ fprintf (stderr, "eek %i,%i %f %f %f %f\n", probe->source_x, probe->source_y, rgba[0], rgba[1],
rgba[2], rgba[3]);
+ gegl_buffer_set (duster->output, GEGL_RECTANGLE(probe->target_x, probe->target_y, 1, 1), 0,
format, &rgba[0], 0);
+ }
+#endif
+ g_hash_table_remove (duster->probes_ht, xy2offset(probe->target_x, probe->target_y));
+ }
+ fprintf (stderr, "\r%2.2f ", y * 100.0 / rect.height);
+ }
+ fprintf (stderr, "\n");
+}
+
+
static gboolean
process (GeglOperation *operation,
GeglBuffer *input,
@@ -115,95 +139,16 @@ process (GeglOperation *operation,
GeglRectangle in_rect = *gegl_buffer_get_extent (input);
GeglRectangle out_rect = *gegl_buffer_get_extent (output);
PixelDuster *duster;
-
- scaled_copy (input, output, o->scale, 1, 14);
+ scaled_copy (input, output, o->scale);
duster = pixel_duster_new (input, output,
&in_rect, &out_rect,
o->seek_distance,
- o->min_neigh,
- o->min_iter,
- o->chance_try,
- o->chance_retry,
+ 1, 1, 1.0, 1.0,
o->scale,
o->scale,
NULL);
- pixel_duster_add_probes (duster);
- pixel_duster_fill (duster);
- pixel_duster_destroy (duster);
-
- scaled_copy (input, output, o->scale, 2, 12);
- duster = pixel_duster_new (input, output,
- &in_rect, &out_rect,
- o->seek_distance,
- o->min_neigh,
- o->min_iter,
- o->chance_try,
- o->chance_retry,
- o->scale,
- o->scale,
- NULL);
- pixel_duster_add_probes (duster);
- pixel_duster_fill (duster);
- pixel_duster_destroy (duster);
-
- scaled_copy (input, output, o->scale, 4, 8);
- duster = pixel_duster_new (input, output,
- &in_rect, &out_rect,
- o->seek_distance,
- o->min_neigh,
- o->min_iter,
- o->chance_try,
- o->chance_retry,
- o->scale,
- o->scale,
- NULL);
- pixel_duster_add_probes (duster);
- pixel_duster_fill (duster);
- pixel_duster_destroy (duster);
-
- scaled_copy (input, output, o->scale, 8, 0);
- duster = pixel_duster_new (input, output,
- &in_rect, &out_rect,
- o->seek_distance,
- o->min_neigh,
- o->min_iter,
- o->chance_try,
- o->chance_retry,
- o->scale,
- o->scale,
- NULL);
- pixel_duster_add_probes (duster);
- pixel_duster_fill (duster);
- pixel_duster_destroy (duster);
-
- scaled_copy (input, output, o->scale, 1, 0);
- duster = pixel_duster_new (input, output,
- &in_rect, &out_rect,
- o->seek_distance,
- o->min_neigh,
- o->min_iter,
- o->chance_try,
- o->chance_retry,
- o->scale,
- o->scale,
- NULL);
- pixel_duster_add_probes (duster);
- pixel_duster_fill (duster);
- pixel_duster_destroy (duster);
-
- scaled_copy (input, output, o->scale, 4, 0);
- duster = pixel_duster_new (input, output,
- &in_rect, &out_rect,
- o->seek_distance,
- o->min_neigh,
- o->min_iter,
- o->chance_try,
- o->chance_retry,
- o->scale,
- o->scale,
- NULL);
- pixel_duster_add_probes (duster);
- pixel_duster_fill (duster);
+ seed_db (duster);
+ improve (duster, input, output, o->scale);
pixel_duster_destroy (duster);
return TRUE;
@@ -213,7 +158,10 @@ static GeglRectangle
get_bounding_box (GeglOperation *operation)
{
GeglProperties *o = GEGL_PROPERTIES (operation);
- GeglRectangle result = *gegl_operation_source_get_bounding_box (operation, "input");
+ 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;
diff --git a/operations/workshop/inpaint.c b/operations/workshop/inpaint.c
index 472ba0c..84d721b 100644
--- a/operations/workshop/inpaint.c
+++ b/operations/workshop/inpaint.c
@@ -23,19 +23,19 @@
#ifdef GEGL_PROPERTIES
-property_int (seek_distance, "seek radius", 8)
+property_int (seek_distance, "seek radius", 96)
value_range (4, 512)
property_int (min_neigh, "min neigh", 2)
value_range (1, 10)
-property_int (min_iter, "min iter", 8)
+property_int (min_iter, "min iter", 4)
value_range (1, 512)
-property_double (chance_try, "try chance", 0.5)
+property_double (chance_try, "try chance", 0.55)
value_range (0.0, 1.0)
-property_double (chance_retry, "retry chance", 0.81)
+property_double (chance_retry, "retry chance", 0.2)
value_range (0.0, 1.0)
#else
@@ -88,9 +88,11 @@ process (GeglOperation *operation,
1.0,
1.0,
operation);
-
+ seed_db (duster);
gegl_buffer_copy (input, NULL, GEGL_ABYSS_NONE, output, NULL);
- pixel_duster_add_probes (duster);
+ fprintf (stderr, "adding transparent probes");
+ pixel_duster_add_probes_for_transparent (duster);
+ fprintf (stderr, "\n");
pixel_duster_fill (duster);
pixel_duster_destroy (duster);
diff --git a/operations/workshop/pixel-duster.h b/operations/workshop/pixel-duster.h
index 69b8fb7..403c806 100644
--- a/operations/workshop/pixel-duster.h
+++ b/operations/workshop/pixel-duster.h
@@ -1,8 +1,14 @@
-/* pixel-duster,
+/* pixel-duster
* a context aware pixel inpainting algorithm
* 2018 (c) Øyvind Kolås pippin gimp org
*/
+/*
+ todo:
+ median/mean for noise redux
+ exclude identicals - when it is obvious
+ */
+
#define POW2(x) ((x)*(x))
#define INITIAL_SCORE 1200000000
@@ -21,8 +27,11 @@ typedef struct
float retry_chance;
float scale_x;
float scale_y;
- GHashTable *ht;
+
+ GHashTable *ht[4096];
+
GHashTable *probes_ht;
+
int order[512][3];
} PixelDuster;
@@ -40,6 +49,12 @@ typedef struct Probe {
#define NEIGHBORHOOD 23
+/* when going through the image preparing the index - only look at the subset
+ * needed pixels - and later when fetching out hashed pixels - investigate
+ * these ones in particular. would only be win for limited inpainting..
+ */
+
+
static void init_order(PixelDuster *duster)
{
int i, x, y;
@@ -124,16 +139,32 @@ static PixelDuster * pixel_duster_new (GeglBuffer *input,
ret->out_rect = *out_rect;
ret->scale_x = scale_x;
ret->scale_y = scale_y;
- ret->ht = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+ for (int i = 0; i < 4096; i++)
+ ret->ht[i] = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
ret->probes_ht = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
init_order (ret);
return ret;
}
+static inline void pixel_duster_remove_probes (PixelDuster *duster)
+{
+ if (duster->probes_ht)
+ {
+ g_hash_table_destroy (duster->probes_ht);
+ duster->probes_ht = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+ }
+}
+
static void pixel_duster_destroy (PixelDuster *duster)
{
- g_hash_table_destroy (duster->ht);
- g_hash_table_destroy (duster->probes_ht);
+ pixel_duster_remove_probes (duster);
+ for (int i = 0; i < 4096; i++)
+ {
+ if (g_hash_table_size (duster->ht[i]))
+ fprintf (stderr, "%i:%i ", i, g_hash_table_size (duster->ht[i]));
+ g_hash_table_destroy (duster->ht[i]);
+ }
+ fprintf (stderr, "\n");
g_free (duster);
}
@@ -147,7 +178,7 @@ static void extract_site (PixelDuster *duster, GeglBuffer *input, int x, int y,
format = babl_format ("R'G'B'A u8");
yformat = babl_format ("Y'aA u8");
}
-
+#if 1
/* figure out which of the up/down/left/right pixels are brightest,
using premultiplied alpha - do punish blank spots */
@@ -159,7 +190,7 @@ static void extract_site (PixelDuster *duster, GeglBuffer *input, int x, int y,
for (int i = 1; i < 4; i++)
if (lum[i*2] > bdir)
bdir = i;
-
+#endif
/* and orient our neighborhood fetching based on that */
switch (bdir)
{
@@ -198,16 +229,11 @@ static void extract_site (PixelDuster *duster, GeglBuffer *input, int x, int y,
break;
}
-
-#if 0
- how to normalize,. go for max of up/down/left/
-#endif
-
}
static inline int u8_rgb_diff (guchar *a, guchar *b)
{
- return POW2(a[0]-b[0]) * 2 + POW2(a[1]-b[1]) * 4 + POW2(a[2]-b[2]);
+ return POW2(a[0]-b[0]) + POW2(a[1]-b[1]) * 2 + POW2(a[2]-b[2]);
}
static int inline
@@ -234,70 +260,81 @@ score_site (PixelDuster *duster,
else
{
/* we score missing cells as if it is a big diff */
- score += ((POW2(36))*3) * 70 / duster->order[i][2];
+ score += ((POW2(36))*3) * 40 / duster->order[i][2];
}
}
return score;
}
-static void
+static Probe *
add_probe (PixelDuster *duster, int target_x, int target_y)
{
Probe *probe = g_malloc0 (sizeof (Probe));
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 = 0;//target_x / duster->scale_x;
+ probe->source_y = 0;//target_y / duster->scale_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 (GeglBuffer *output, Probe *probe, int rel_x, int rel_y)
+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 int
-probe_neighbors (GeglBuffer *output, Probe *probe, int min)
+probe_neighbors (PixelDuster *duster, GeglBuffer *output, Probe *probe, int min)
{
int found = 0;
- if (probe_rel_is_set (output, probe, -1, 0)) found ++;
+ if (probe_rel_is_set (duster, output, probe, -1, 0)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 1, 0)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 1, 0)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 0, 1)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 0, 1)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 0, -1)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 0, -1)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 1, 1)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 1, 1)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 2, 0)) found ++;
+ if (probe_rel_is_set (duster, output, probe, -1,-1)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 0, 2)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 1,-1)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, -2, 0)) found ++;
+ if (probe_rel_is_set (duster, output, probe, -1, 1)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 0, -2)) found ++;
+#if 0
+ if (probe_rel_is_set (duster, output, probe, 2, 0)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, -1,-1)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 0, 2)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 1,-1)) found ++;
+ if (probe_rel_is_set (duster, output, probe, -2, 0)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, -1, 1)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 0, -2)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, -3, 0)) found ++;
+ if (probe_rel_is_set (duster, output, probe, -3, 0)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 3, 0)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 3, 0)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 0, 3)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 0, 3)) found ++;
if (found >=min) return found;
- if (probe_rel_is_set (output, probe, 0, -3)) found ++;
+ if (probe_rel_is_set (duster, output, probe, 0, -3)) found ++;
+#endif
return found;
}
@@ -310,7 +347,7 @@ spread_relative (PixelDuster *duster, Probe *probe, int dx, int dy)
format = babl_format ("RGBA float");
/* spread our resulting neighborhodo to unset neighbors */
- if (!probe_rel_is_set (duster->output, probe, dx, dy))
+ if (!probe_rel_is_set (duster, duster->output, probe, dx, dy))
{
Probe *neighbor_probe = g_hash_table_lookup (duster->probes_ht,
xy2offset(probe->target_x + dx, probe->target_y + dy));
@@ -334,71 +371,152 @@ spread_relative (PixelDuster *duster, Probe *probe, int dx, int dy)
return 0;
}
+static int site_subset (guchar *site)
+{
+ int a = (site[4 + 1]/16) +
+ (site[8 + 1]/16) * 16 +
+ (site[12 + 1]/16) * 16 * 16;
+ return a;
+}
+
+
+static void site_subset2 (guchar *site, gint *min, gint *max)
+{
+ int v[3] = {(site[4 + 1]/4), (site[8 + 1]/4), (site[12 + 1]/4)};
+ for (int i = 0; i < 3; i ++)
+ {
+ if (site[(4 + 4 *i)+3] == 0)
+ {
+ min[i] = 0;
+ max[i] = 15;
+ }
+ else
+ {
+ switch (v[i] % 4)
+ {
+ case 0: min[i] = v[i]/4-1; max[i] = v[i]/4;
+ if (min[i] < 0) min[i] = 0;
+ break;
+ case 1: min[i] = v[i]/4; max[i] = v[i]/4; break;
+ case 2: min[i] = v[i]/4; max[i] = v[i]/4; break;
+ case 3: min[i] = v[i]/4; max[i] = v[i]/4+1;
+ if (max[i] > 15) max[i] = 15;
+ break;
+ }
+ }
+ }
+}
+
+
+static guchar *ensure_hay (PixelDuster *duster, int x, int y, int subset)
+{
+ guchar *hay = NULL;
+
+ if (subset >= 0)
+ hay = g_hash_table_lookup (duster->ht[subset], xy2offset(x, y));
+
+ if (!hay)
+ {
+ hay = g_malloc (4 * NEIGHBORHOOD);
+ extract_site (duster, duster->input, x, y, hay);
+ if (subset < 0)
+ {
+ subset = site_subset (hay);
+ if (hay[3] == 0)
+ {
+ g_free (hay);
+ return NULL;
+ }
+ }
+ g_hash_table_insert (duster->ht[subset], xy2offset(x, y), hay);
+ }
+
+ return hay;
+}
+
+static void compare_needle (gpointer key, gpointer value, gpointer data)
+{
+ void **ptr = data;
+ PixelDuster *duster = ptr[0];
+ Probe *probe = ptr[1];
+ guchar *needle = ptr[2];
+ guchar *hay = value;
+ gint offset = GPOINTER_TO_INT (key);
+ gint x = offset % 65536;
+ gint y = offset / 65536;
+ int score;
+
+ if (duster->scale_x == 1.0 && x == probe->target_x &&
+- duster->scale_y == 1.0 && y == probe->target_y )
+ return;
+
+ score = score_site (duster, &needle[0], hay, probe->score);
+
+ if (score < probe->score)
+ {
+ probe->source_x = x;
+ probe->source_y = y;
+ probe->score = score;
+ }
+}
+
static int probe_improve (PixelDuster *duster,
Probe *probe)
{
guchar needle[4 * NEIGHBORHOOD];
gint dst_x = probe->target_x;
gint dst_y = probe->target_y;
- gint *best_x = &probe->source_x;
- gint *best_y = &probe->source_y;
- gint start_x = probe->source_x;
- gint start_y = probe->source_y;
+ void *ptr[3] = {duster, probe, &needle[0]};
int old_score = probe->score;
static const Babl *format = NULL;
+ int set_start[3];
+ int set_end[3];
+
if (!format)
format = babl_format ("RGBA float");
- extract_site (duster, duster->output, dst_x, dst_y, &needle[0]);
-
-#if 0
- if (probe->score < 10000)
- return 0;
-#endif
-
- for (int dy = -duster->seek_radius; dy < duster->seek_radius; dy ++)
- for (int dx = -duster->seek_radius ; dx < duster->seek_radius; dx ++)
- {
- int score;
- guchar *hay = NULL;
- if (duster->scale_x == 1.0 && start_x + dx == dst_x &&
- duster->scale_y == 1.0 && start_y + dy == dst_y)
- continue;
-#if 1
- if (start_x + dx < 5 || start_y + dy < 5 ||
- start_x + dx > duster->in_rect.width - 5 ||
- start_y + dy > duster->in_rect.height - 5)
- continue;
-#endif
- hay = g_hash_table_lookup (duster->ht, xy2offset(start_x + dx, start_y + dy));
- if (!hay)
- {
- hay = g_malloc (4 * NEIGHBORHOOD);
- extract_site (duster, duster->input, start_x + dx, start_y + dy, hay);
- g_hash_table_insert (duster->ht, xy2offset(start_x + dx, start_y + dy), hay);
-
- }
+ extract_site (duster, duster->output, dst_x, dst_y, &needle[0]);
+ site_subset2 (&needle[0], set_start, set_end);
- score = score_site (duster, &needle[0], hay, probe->score);
+ if (set_end[0] == set_start[0] &&
+ set_end[1] == set_start[1] &&
+ set_end[2] == set_start[2])
+ {
+ int subset = set_start[0] + set_start[1] * 16 + set_start[2] * 16 * 16;
+ g_hash_table_foreach (duster->ht[subset], compare_needle, ptr);
+ }
+ else
+ {
+ int i[3];
+ for (i[0]=0;i[0]<3;i[0]++)
+ if (set_start[i[0]] < 0)
+ set_start[i[0]] = 0;
+ for (i[0]=0;i[0]<3;i[0]++)
+ if (set_end[i[0]] > 15)
+ set_end[i[0]] = 15;
+
+
+ for (i[0] = set_start[0]; i[0] <= set_end[0]; i[0]++)
+ for (i[1] = set_start[1]; i[1] <= set_end[1]; i[1]++)
+ for (i[2] = set_start[2]; i[2] <= set_end[2]; i[2]++)
+ {
+ int subset = i[0] + i[1] * 16 + i[2] * 16 * 16;
+ g_hash_table_foreach (duster->ht[subset], compare_needle, ptr);
+ }
+ }
- if (score < probe->score)
- {
- *best_x = start_x + dx;
- *best_y = start_y + dy;
- probe->score = score;
- }
- }
if (probe->score == old_score)
- return -1;
+ return -1;
+#if 0
spread_relative (duster, probe, -1, -1);
spread_relative (duster, probe, -1, 0);
spread_relative (duster, probe, 0, -1);
spread_relative (duster, probe, 1, 0);
spread_relative (duster, probe, 0, 1);
-
+#endif
probe->age++;
- if (probe->age > 5)
+ if (probe->age > 15)
{
g_hash_table_remove (duster->probes_ht, xy2offset(probe->target_x, probe->target_y));
}
@@ -406,7 +524,7 @@ static int probe_improve (PixelDuster *duster,
return 0;
}
-static void pixel_duster_add_probes (PixelDuster *duster)
+static inline void pixel_duster_add_probes_for_transparent (PixelDuster *duster)
{
const Babl *format = babl_format ("RGBA float");
GeglBufferIterator *i = gegl_buffer_iterator_new (duster->output,
@@ -439,7 +557,7 @@ static void pixel_duster_add_probes (PixelDuster *duster)
}
}
-static void pixel_duster_fill (PixelDuster *duster)
+static inline void pixel_duster_fill (PixelDuster *duster)
{
const Babl *format = babl_format ("RGBA float");
gint missing = 1;
@@ -474,14 +592,17 @@ static void pixel_duster_fill (PixelDuster *duster)
probe->source_y == probe->target_y))
try_replace = 0;
- if ((rand()%100)/100.0 < duster->try_chance && probe_neighbors (duster->output, probe,
duster->minimum_neighbors) >= duster->minimum_neighbors)
+ if ((rand()%100)/100.0 < duster->try_chance &&
+ probe_neighbors (duster, duster->output, probe, duster->minimum_neighbors) >=
+ duster->minimum_neighbors)
{
if(try_replace)
probe->score = INITIAL_SCORE;
if (probe_improve (duster, probe) == 0)
{
gfloat rgba[4];
- gegl_buffer_sample (duster->input, probe->source_x, probe->source_y, NULL, &rgba[0], format,
GEGL_SAMPLER_NEAREST, 0);
+ gegl_buffer_sample (duster->input, probe->source_x, probe->source_y,
+ NULL, &rgba[0], format, GEGL_SAMPLER_NEAREST, 0);
if (rgba[3] <= 0.01)
fprintf (stderr, "eek %i,%i %f %f %f %f\n", probe->source_x, probe->source_y, rgba[0], rgba[1],
rgba[2], rgba[3]);
gegl_buffer_set (duster->output, GEGL_RECTANGLE(probe->target_x, probe->target_y, 1, 1), 0,
format, &rgba[0], 0);
@@ -500,3 +621,16 @@ static void pixel_duster_fill (PixelDuster *duster)
fprintf (stderr, "\n");
#endif
}
+
+static void seed_db (PixelDuster *duster)
+{
+ fprintf (stderr, "db seed");
+
+ for (gint y = 0; y < duster->in_rect.height; y++)
+ for (gint x = 0; x < duster->in_rect.width; x++)
+ {
+ ensure_hay (duster, x, y, -1);
+ }
+
+ fprintf (stderr, "ed\n");
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]