[gegl] npd: NPD operation uses GEGL sampler and operates in RGBA float
- From: Mikael Magnusson <mikachu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] npd: NPD operation uses GEGL sampler and operates in RGBA float
- Date: Fri, 27 Feb 2015 18:32:40 +0000 (UTC)
commit c33fb4516553b1c68b61139b92286b4d55e8ef72
Author: Marek Dvoroznak <dvoromar gmail com>
Date: Wed Dec 11 06:08:15 2013 +0100
npd: NPD operation uses GEGL sampler and operates in RGBA float
libs/npd/graphics.c | 101 ++++++++++++++++++++----------------
libs/npd/graphics.h | 94 +++++++++++++++++++--------------
libs/npd/npd_common.h | 3 +-
libs/npd/npd_gegl.c | 7 ++-
libs/npd/npd_gegl.h | 24 +++++----
libs/npd/npd_math.c | 4 +-
libs/npd/npd_math.h | 14 +++---
operations/external/npd.c | 128 +++++++++++++++++++++++++++++++--------------
8 files changed, 229 insertions(+), 146 deletions(-)
---
diff --git a/libs/npd/graphics.c b/libs/npd/graphics.c
index 8ca26a3..1cb8897 100644
--- a/libs/npd/graphics.c
+++ b/libs/npd/graphics.c
@@ -54,7 +54,7 @@ npd_bilinear_color_interpolation (NPDColor *I0,
out->a = npd_bilinear_interpolation (I0->a, I1->a, I2->a, I3->a, dx, dy);
}
-static gfloat
+gfloat
npd_blend_band (gfloat src,
gfloat dst,
gfloat src_alpha,
@@ -70,24 +70,60 @@ npd_blend_colors (NPDColor *src,
NPDColor *dst,
NPDColor *out_color)
{
-#ifdef NPD_RGBA_FLOAT
- gfloat src_A = src->a,
- dst_A = dst->a;
-#else
gfloat src_A = src->a / 255.0,
dst_A = dst->a / 255.0;
-#endif
gfloat out_alpha = src_A + dst_A * (1 - src_A);
gfloat out_alpha_recip = 1 / out_alpha;
out_color->r = npd_blend_band (src->r, dst->r, src_A, dst_A, out_alpha_recip);
out_color->g = npd_blend_band (src->g, dst->g, src_A, dst_A, out_alpha_recip);
out_color->b = npd_blend_band (src->b, dst->b, src_A, dst_A, out_alpha_recip);
-#ifdef NPD_RGBA_FLOAT
- out_color->a = out_alpha;
-#else
out_color->a = out_alpha * 255;
-#endif
+}
+
+void
+npd_process_pixel_bilinear (NPDImage *input_image,
+ gfloat ix,
+ gfloat iy,
+ NPDImage *output_image,
+ gfloat ox,
+ gfloat oy,
+ NPDSettings settings)
+{
+ gint fx, fy;
+ gfloat dx, dy;
+ NPDColor I0, interpolated, *final_color;
+
+ fx = floor (ix);
+ fy = floor (iy);
+
+ npd_get_pixel_color (input_image, fx, fy, &I0);
+ final_color = &I0;
+
+ /* bilinear interpolation */
+ if (settings & NPD_BILINEAR_INTERPOLATION)
+ {
+ NPDColor I1, I2, I3;
+
+ dx = ix - fx;
+ dy = iy - fy;
+
+ npd_get_pixel_color (input_image, fx + 1, fy, &I1);
+ npd_get_pixel_color (input_image, fx, fy + 1, &I2);
+ npd_get_pixel_color (input_image, fx + 1, fy + 1, &I3);
+ npd_bilinear_color_interpolation (&I0, &I1, &I2, &I3, dx, dy, &interpolated);
+ final_color = &interpolated;
+ }
+
+ /* alpha blending */
+ if (settings & NPD_ALPHA_BLENDING)
+ {
+ NPDColor dest;
+ npd_get_pixel_color (output_image, ox, oy, &dest);
+ npd_blend_colors (final_color, &dest, final_color);
+ }
+
+ npd_set_pixel_color (output_image, ox, oy, final_color);
}
static void
@@ -99,47 +135,18 @@ npd_draw_texture_line (gint x1,
NPDImage *output_image,
NPDSettings settings)
{
- gint x, fx, fy;
- gfloat dx, dy;
+ gint x;
for (x = x1; x <= x2; x++)
{
NPDPoint p, q;
- NPDColor I0, interpolated, *final;
q.x = x; q.y = y;
npd_apply_transformation (A, &q, &p);
- fx = floor (p.x);
- fy = floor (p.y);
-
- npd_get_pixel_color (input_image, fx, fy, &I0);
- final = &I0;
-
- /* bilinear interpolation */
- if (settings & NPD_BILINEAR_INTERPOLATION)
- {
- NPDColor I1, I2, I3;
-
- dx = p.x - fx;
- dy = p.y - fy;
-
- npd_get_pixel_color (input_image, fx + 1, fy, &I1);
- npd_get_pixel_color (input_image, fx, fy + 1, &I2);
- npd_get_pixel_color (input_image, fx + 1, fy + 1, &I3);
- npd_bilinear_color_interpolation (&I0, &I1, &I2, &I3, dx, dy, &interpolated);
- final = &interpolated;
- }
-
- /* alpha blending */
- if (settings & NPD_ALPHA_BLENDING)
- {
- NPDColor dest;
- npd_get_pixel_color (output_image, x, y, &dest);
- npd_blend_colors (final, &dest, final);
- }
-
- npd_set_pixel_color (output_image, x, y, final);
+ npd_process_pixel (input_image, p.x, p.y,
+ output_image, x, y,
+ settings);
}
}
@@ -354,7 +361,7 @@ npd_create_mesh (NPDModel *model,
gint square_size = model->mesh_square_size;
NPDImage *image = model->reference_image;
gint i, cy, cx, y, x, r, c, ow, oh;
- NPDColor pixel_color = { 0, 0, 0, 0 };
+ NPDColor pixel_color;
GArray *squares;
gint *sq2id;
gboolean *empty_squares;
@@ -549,7 +556,6 @@ npd_create_model_from_image (NPDModel *model,
npd_create_mesh (model, width, height, position_x, position_y);
}
-
void
npd_draw_mesh (NPDModel *model,
NPDDisplay *display)
@@ -572,3 +578,8 @@ npd_draw_mesh (NPDModel *model,
npd_draw_line (display, p1->x, p1->y, first->x, first->y);
}
}
+
+void (*npd_process_pixel) (NPDImage*, gfloat, gfloat, NPDImage*, gfloat, gfloat, NPDSettings) = NULL;
+void (*npd_draw_line) (NPDDisplay*, gfloat, gfloat, gfloat, gfloat) = NULL;
+void (*npd_get_pixel_color) (NPDImage*, gint, gint, NPDColor*) = NULL;
+void (*npd_set_pixel_color) (NPDImage*, gint, gint, NPDColor*) = NULL;
diff --git a/libs/npd/graphics.h b/libs/npd/graphics.h
index 69c272d..89c1ab4 100644
--- a/libs/npd/graphics.h
+++ b/libs/npd/graphics.h
@@ -24,20 +24,17 @@
#include "npd_common.h"
-//#define NPD_RGBA_FLOAT
-
-struct _NPDColor {
-#ifdef NPD_RGBA_FLOAT
- gfloat r;
- gfloat g;
- gfloat b;
- gfloat a;
-#else
- guint8 r;
- guint8 g;
- guint8 b;
- guint8 a;
-#endif
+struct _NPDColor
+{
+ union {
+ guint32 color;
+ struct {
+ guint8 r;
+ guint8 g;
+ guint8 b;
+ guint8 a;
+ };
+ };
};
typedef enum
@@ -46,30 +43,49 @@ typedef enum
NPD_ALPHA_BLENDING = 1 << 1
} NPDSettings;
-void npd_create_model_from_image (NPDModel *model,
- NPDImage *image,
- gint width,
- gint height,
- gint position_x,
- gint position_y,
- gint square_size);
-void npd_draw_model_into_image (NPDModel *model,
- NPDImage *image);
-void npd_draw_mesh (NPDModel *model,
- NPDDisplay *display);
-gboolean npd_is_color_transparent (NPDColor *color);
-void (*npd_draw_line) (NPDDisplay *display,
- gfloat x0,
- gfloat y0,
- gfloat x1,
- gfloat y1);
-void (*npd_get_pixel_color) (NPDImage *image,
- gint x,
- gint y,
- NPDColor *color);
-void (*npd_set_pixel_color) (NPDImage *image,
- gint x,
- gint y,
- NPDColor *color);
+void npd_create_model_from_image (NPDModel *model,
+ NPDImage *image,
+ gint width,
+ gint height,
+ gint position_x,
+ gint position_y,
+ gint square_size);
+void npd_draw_model_into_image (NPDModel *model,
+ NPDImage *image);
+void npd_draw_mesh (NPDModel *model,
+ NPDDisplay *display);
+gboolean npd_is_color_transparent (NPDColor *color);
+gfloat npd_blend_band (gfloat src,
+ gfloat dst,
+ gfloat src_alpha,
+ gfloat dst_alpha,
+ gfloat out_alpha_recip);
+extern void (*npd_draw_line) (NPDDisplay *display,
+ gfloat x0,
+ gfloat y0,
+ gfloat x1,
+ gfloat y1);
+extern void (*npd_process_pixel) (NPDImage *input_image,
+ gfloat ix,
+ gfloat iy,
+ NPDImage *output_image,
+ gfloat ox,
+ gfloat oy,
+ NPDSettings settings);
+void npd_process_pixel_bilinear (NPDImage *input_image,
+ gfloat ix,
+ gfloat iy,
+ NPDImage *output_image,
+ gfloat ox,
+ gfloat oy,
+ NPDSettings settings);
+extern void (*npd_get_pixel_color) (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color);
+extern void (*npd_set_pixel_color) (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color);
#endif /*__NPD_GRAPHICS_H__ */
diff --git a/libs/npd/npd_common.h b/libs/npd/npd_common.h
index fe57697..40a05ed 100644
--- a/libs/npd/npd_common.h
+++ b/libs/npd/npd_common.h
@@ -94,9 +94,10 @@ typedef struct
} NPDModel;
#define npd_init(set_pixel, get_pixel, \
- draw_line) \
+ process_pixel, draw_line) \
npd_set_pixel_color = set_pixel; \
npd_get_pixel_color = get_pixel; \
+npd_process_pixel = process_pixel; \
npd_draw_line = draw_line;
void npd_init_model (NPDModel *model);
diff --git a/libs/npd/npd_gegl.c b/libs/npd/npd_gegl.c
index 0d5ea3a..31c31c4 100644
--- a/libs/npd/npd_gegl.c
+++ b/libs/npd/npd_gegl.c
@@ -65,7 +65,7 @@ npd_gegl_set_pixel_color (NPDImage *image,
if (x > -1 && x < image->width &&
y > -1 && y < image->height)
{
- gint position = y * image->rowstride + 4 * x;
+ gint position = 4 * (y * image->width + x);
image->buffer[position + 0] = color->r;
image->buffer[position + 1] = color->g;
@@ -83,7 +83,7 @@ npd_gegl_get_pixel_color (NPDImage *image,
if (x > -1 && x < image->width &&
y > -1 && y < image->height)
{
- gint position = y * image->rowstride + 4 * x;
+ gint position = 4 * (y * image->width + x);
color->r = image->buffer[position + 0];
color->g = image->buffer[position + 1];
@@ -116,6 +116,9 @@ npd_gegl_init_image (NPDImage *image,
image->gegl_buffer = gegl_buffer;
image->width = gegl_buffer_get_width (gegl_buffer);
image->rowstride = image->width * babl_format_get_bytes_per_pixel (format);
+ image->length = babl_format_get_n_components (format) * gegl_buffer_get_pixel_count (gegl_buffer);
image->height = gegl_buffer_get_height (gegl_buffer);
image->format = format;
+ image->buffer = NULL;
+ image->buffer_f = NULL;
}
diff --git a/libs/npd/npd_gegl.h b/libs/npd/npd_gegl.h
index 855473e..edba11d 100644
--- a/libs/npd/npd_gegl.h
+++ b/libs/npd/npd_gegl.h
@@ -32,22 +32,24 @@ struct _NPDImage
gint height;
NPDPoint position;
gint rowstride;
+ gint length;
GeglBuffer *gegl_buffer;
guchar *buffer;
+ gfloat *buffer_f;
const Babl *format;
+ GeglSamplerType sampler_type;
};
-void npd_gegl_set_pixel_color (NPDImage *image,
- gint x,
- gint y,
- NPDColor *color);
-
-void npd_gegl_get_pixel_color (NPDImage *image,
- gint x,
- gint y,
- NPDColor *color);
-void npd_gegl_open_buffer (NPDImage *image);
-void npd_gegl_close_buffer (NPDImage *image);
+void npd_gegl_set_pixel_color (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color);
+void npd_gegl_get_pixel_color (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color);
+void npd_gegl_open_buffer (NPDImage *image);
+void npd_gegl_close_buffer (NPDImage *image);
void npd_gegl_init_image (NPDImage *image,
GeglBuffer *gegl_buffer,
const Babl *format);
diff --git a/libs/npd/npd_math.c b/libs/npd/npd_math.c
index b14f73f..b2dd1d5 100644
--- a/libs/npd/npd_math.c
+++ b/libs/npd/npd_math.c
@@ -41,7 +41,7 @@ gfloat
npd_SED (NPDPoint *p1,
NPDPoint *p2)
{
- gint dx = p1->x - p2->x;
- gint dy = p1->y - p2->y;
+ gfloat dx = p1->x - p2->x;
+ gfloat dy = p1->y - p2->y;
return dx * dx + dy * dy;
}
diff --git a/libs/npd/npd_math.h b/libs/npd/npd_math.h
index 1b3e624..a48933f 100644
--- a/libs/npd/npd_math.h
+++ b/libs/npd/npd_math.h
@@ -39,12 +39,12 @@ void npd_compute_affinity (NPDPoint *p11,
void npd_apply_transformation (NPDMatrix *T,
NPDPoint *src,
NPDPoint *dest);
-gboolean npd_equal_floats_epsilon (gfloat a,
- gfloat b,
- gfloat epsilon);
-gboolean npd_equal_floats (gfloat a,
- gfloat b);
-gfloat npd_SED (NPDPoint *p1,
- NPDPoint *p2);
+gboolean npd_equal_floats_epsilon (gfloat a,
+ gfloat b,
+ gfloat epsilon);
+gboolean npd_equal_floats (gfloat a,
+ gfloat b);
+gfloat npd_SED (NPDPoint *p1,
+ NPDPoint *p2);
#endif /* __NPD_MATH_H__ */
diff --git a/operations/external/npd.c b/operations/external/npd.c
index 12182fa..dda01d6 100644
--- a/operations/external/npd.c
+++ b/operations/external/npd.c
@@ -42,6 +42,15 @@ gegl_chant_boolean (MLS_weights, _("MLS weights"),
gegl_chant_double (MLS_weights_alpha, _("MLS weights alpha"),
0.1, 2.0, 1.0,
_("Alpha parameter of MLS weights"))
+
+gegl_chant_boolean (preserve_model, _("preserve model"),
+ FALSE,
+ _("When TRUE the model will not be freed"))
+
+gegl_chant_enum (sampler_type, _("Sampler"),
+ GeglSamplerType, gegl_sampler_type,
+ GEGL_SAMPLER_CUBIC,
+ _("Sampler used internally"))
#else
#define GEGL_CHANT_TYPE_FILTER
@@ -61,7 +70,7 @@ struct _NPDDisplay
typedef struct
{
gboolean first_run;
- NPDModel model;
+ NPDModel *model;
} NPDProperties;
static void
@@ -69,18 +78,45 @@ prepare (GeglOperation *operation)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
NPDProperties *props;
-
if (o->chant_data == NULL)
{
props = g_new (NPDProperties, 1);
- props->first_run = TRUE;
- o->chant_data = props;
+ props->first_run = TRUE;
+ props->model = o->model;
+ o->chant_data = props;
+ }
+
+ gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
+}
+
+static void
+npd_gegl_process_pixel (NPDImage *input_image,
+ gfloat ix,
+ gfloat iy,
+ NPDImage *output_image,
+ gfloat ox,
+ gfloat oy,
+ NPDSettings settings)
+{
+ if (ox > -1 && ox < output_image->width &&
+ oy > -1 && oy < output_image->height)
+ {
+ gint position = 4 * (((gint) oy) * output_image->width + ((gint) ox));
+ gegl_buffer_sample (input_image->gegl_buffer, ix, iy, NULL,
+ &output_image->buffer_f[position], output_image->format,
+ output_image->sampler_type, GEGL_ABYSS_NONE);
}
+}
- gegl_operation_set_format (operation, "input",
- babl_format ("RGBA float"));
- gegl_operation_set_format (operation, "output",
- babl_format ("RGBA float"));
+static void
+npd_gegl_get_pixel_color_f (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color)
+{
+ gegl_buffer_sample (image->gegl_buffer, x, y, NULL,
+ &color->color, babl_format ("RGBA u8"),
+ GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
}
static gboolean
@@ -90,41 +126,48 @@ process (GeglOperation *operation,
const GeglRectangle *roi,
gint level)
{
- GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- const Babl *format = babl_format ("RGBA u8");
- NPDProperties *props = o->chant_data;
- NPDModel *model = &props->model;
- gint length = gegl_buffer_get_pixel_count (input) * 4;
- NPDDisplay *display = model->display;
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ const Babl *format_f = babl_format ("RGBA float");
+ NPDProperties *props = o->chant_data;
+ NPDModel *model = props->model;
+ gboolean have_model = model != NULL;
+ NPDDisplay *display = NULL;
if (props->first_run)
{
NPDImage *input_image = g_new (NPDImage, 1);
display = g_new (NPDDisplay, 1);
- npd_init (npd_gegl_set_pixel_color,
- npd_gegl_get_pixel_color,
- NULL);
+ npd_init (NULL,
+ npd_gegl_get_pixel_color_f,
+ npd_gegl_process_pixel, NULL);
- npd_gegl_init_image (input_image, input, format);
- input_image->buffer = g_new0 (guchar, gegl_buffer_get_pixel_count (input) * 4);
- gegl_buffer_get (input, NULL, 1.0, format, input_image->buffer,
- GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+ npd_gegl_init_image (&display->image, output, format_f);
+ display->image.sampler_type = o->sampler_type;
+ npd_gegl_init_image (input_image, input, gegl_buffer_get_format (output));
- npd_gegl_init_image (&display->image, output, format);
- npd_gegl_open_buffer (&display->image);
+ if (!have_model)
+ {
+ model = props->model = o->model = g_new (NPDModel, 1);
+ gegl_buffer_copy (input, NULL, output, NULL);
+ display->image.buffer_f = (gfloat*) gegl_buffer_linear_open (display->image.gegl_buffer,
+ NULL,
+ &display->image.rowstride,
+ format_f);
+ npd_create_model_from_image (model, input_image,
+ input_image->width, input_image->height,
+ 0, 0, o->square_size);
+ }
+ model->reference_image = input_image;
model->display = display;
- npd_create_model_from_image (model, input_image,
- input_image->width, input_image->height,
- 0, 0, o->square_size);
- o->model = model;
- memcpy (display->image.buffer, input_image->buffer, length);
-
props->first_run = FALSE;
}
- else
+
+ if (have_model)
{
+ display = model->display;
+
npd_set_deformation_type (model, o->ASAP_deformation, o->MLS_weights);
if (o->MLS_weights &&
@@ -134,13 +177,17 @@ process (GeglOperation *operation,
npd_compute_MLS_weights (model);
}
- npd_gegl_open_buffer (&display->image);
- memset (display->image.buffer, 0, length);
+ gegl_buffer_clear (display->image.gegl_buffer, NULL);
+ display->image.buffer_f = (gfloat*) gegl_buffer_linear_open (display->image.gegl_buffer,
+ NULL,
+ &display->image.rowstride,
+ format_f);
+
npd_deform_model (model, o->rigidity);
npd_draw_model_into_image (model, &display->image);
}
- npd_gegl_close_buffer (&display->image);
+ gegl_buffer_linear_close (display->image.gegl_buffer, display->image.buffer_f);
return TRUE;
}
@@ -152,14 +199,17 @@ finalize (GObject *object)
if (o->chant_data)
{
- NPDProperties *props = o->chant_data;
- NPDModel *model = &props->model;
- NPDDisplay *display = model->display;
+ NPDProperties *props = o->chant_data;
+ NPDModel *model = props->model;
+ NPDDisplay *display = model->display;
- g_free (model->reference_image->buffer);
- g_free (model->reference_image);
g_free (display);
- npd_destroy_model (model);
+ g_free (model->reference_image);
+ if (!o->preserve_model)
+ {
+ npd_destroy_model (model);
+ g_free (model);
+ }
o->chant_data = NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]