summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTomas Farago <sensej007@email.cz>2021-12-15 16:22:05 +0100
committerTomas Farago <sensej007@email.cz>2021-12-15 16:22:05 +0100
commite032d752dc9e4723445d82a099cc02163df3ddd3 (patch)
tree86430966d84e68633da666f470f98aa5a045157c /src
parent4c5d52debe42d0ad3d04df03e0bb462d11854b51 (diff)
downloadufo-filters-e032d752dc9e4723445d82a099cc02163df3ddd3.tar.gz
ufo-filters-e032d752dc9e4723445d82a099cc02163df3ddd3.tar.bz2
ufo-filters-e032d752dc9e4723445d82a099cc02163df3ddd3.tar.xz
ufo-filters-e032d752dc9e4723445d82a099cc02163df3ddd3.zip
horizontal-interpolate: add use-one-sided-gradient
Which gives finer contol over what happens when the mask spans to the border.
Diffstat (limited to 'src')
-rw-r--r--src/kernels/interpolator.cl23
-rw-r--r--src/ufo-horizontal-interpolate-task.c59
2 files changed, 75 insertions, 7 deletions
diff --git a/src/kernels/interpolator.cl b/src/kernels/interpolator.cl
index 6600af9..4d4eae8 100644
--- a/src/kernels/interpolator.cl
+++ b/src/kernels/interpolator.cl
@@ -53,7 +53,8 @@ interpolate_horizontally (global float *a,
kernel void
interpolate_mask_horizontally (global float *input,
global float *mask,
- global float *output)
+ global float *output,
+ const int use_gradient)
{
const int idx = get_global_id (0);
const int idy = get_global_id (1);
@@ -73,9 +74,13 @@ interpolate_mask_horizontally (global float *input,
if (left < 0) {
/* Mask spans to the left border, use only the right value */
if (right < width - 1) {
- /* There are two valid pixels on the right, use gradient */
- diff = input[offset + right] - input[offset + right + 1];
- output[offset + idx] = input[offset + right] + diff * (right - idx);
+ if (use_gradient) {
+ /* There are two valid pixels on the right, use gradient */
+ diff = input[offset + right] - input[offset + right + 1];
+ output[offset + idx] = input[offset + right] + diff * (right - idx);
+ } else {
+ output[offset + idx] = input[offset + right];
+ }
} else if (right == width - 1) {
/* There is only one valid pixel on the right, which is the only
* valid pixel in this row, so use it's value everywhere */
@@ -87,9 +92,13 @@ interpolate_mask_horizontally (global float *input,
} else if (right >= width) {
/* Mask spans to the right border, use only the left value */
if (left > 0) {
- /* There are two valid pixels on the left, use gradient */
- diff = input[offset + left] - input[offset + left - 1];
- output[offset + idx] = input[offset + left] + diff * (idx - left);
+ if (use_gradient) {
+ /* There are two valid pixels on the left, use gradient */
+ diff = input[offset + left] - input[offset + left - 1];
+ output[offset + idx] = input[offset + left] + diff * (idx - left);
+ } else {
+ output[offset + idx] = input[offset + left];
+ }
} else if (left == 0) {
/* There is only one valid pixel on the left, which is the only
* valid pixel in this row, so use it's value everywhere */
diff --git a/src/ufo-horizontal-interpolate-task.c b/src/ufo-horizontal-interpolate-task.c
index 436018b..abe6d27 100644
--- a/src/ufo-horizontal-interpolate-task.c
+++ b/src/ufo-horizontal-interpolate-task.c
@@ -29,6 +29,7 @@
struct _UfoHorizontalInterpolateTaskPrivate {
cl_kernel kernel;
+ gboolean use_onesided_gradient;
};
static void ufo_task_interface_init (UfoTaskIface *iface);
@@ -39,6 +40,14 @@ G_DEFINE_TYPE_WITH_CODE (UfoHorizontalInterpolateTask, ufo_horizontal_interpolat
#define UFO_HORIZONTAL_INTERPOLATE_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_HORIZONTAL_INTERPOLATE_TASK, UfoHorizontalInterpolateTaskPrivate))
+enum {
+ PROP_0,
+ PROP_USE_ONESIDED_GRADIENT,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
UfoNode *
ufo_horizontal_interpolate_task_new (void)
{
@@ -106,6 +115,7 @@ ufo_horizontal_interpolate_task_process (UfoTask *task,
UfoProfiler *profiler;
cl_command_queue cmd_queue;
cl_mem mask_in_mem, in_mem, out_mem;
+ gint use_onesided_gradient;
priv = UFO_HORIZONTAL_INTERPOLATE_TASK_GET_PRIVATE (task);
node = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task)));
@@ -114,16 +124,53 @@ ufo_horizontal_interpolate_task_process (UfoTask *task,
mask_in_mem = ufo_buffer_get_device_array (inputs[1], cmd_queue);
out_mem = ufo_buffer_get_device_array (output, cmd_queue);
profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task));
+ use_onesided_gradient = (gint) priv->use_onesided_gradient;
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 0, sizeof (cl_mem), &in_mem));
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 1, sizeof (cl_mem), &mask_in_mem));
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 2, sizeof (cl_mem), &out_mem));
+ UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 3, sizeof (cl_int), &use_onesided_gradient));
ufo_profiler_call (profiler, cmd_queue, priv->kernel, 2, requisition->dims, NULL);
return TRUE;
}
static void
+ufo_horizontal_interpolate_task_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ UfoHorizontalInterpolateTaskPrivate *priv = UFO_HORIZONTAL_INTERPOLATE_TASK_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_USE_ONESIDED_GRADIENT:
+ priv->use_onesided_gradient = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ufo_horizontal_interpolate_task_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ UfoHorizontalInterpolateTaskPrivate *priv = UFO_HORIZONTAL_INTERPOLATE_TASK_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_USE_ONESIDED_GRADIENT:
+ g_value_set_boolean (value, priv->use_onesided_gradient);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+static void
ufo_horizontal_interpolate_task_finalize (GObject *object)
{
UfoHorizontalInterpolateTaskPrivate *priv = UFO_HORIZONTAL_INTERPOLATE_TASK_GET_PRIVATE (object);
@@ -153,9 +200,20 @@ ufo_horizontal_interpolate_task_class_init (UfoHorizontalInterpolateTaskClass *k
GObjectClass *oclass = G_OBJECT_CLASS (klass);
UfoNodeClass *node_class = UFO_NODE_CLASS (klass);
+ oclass->set_property = ufo_horizontal_interpolate_task_set_property;
+ oclass->get_property = ufo_horizontal_interpolate_task_get_property;
oclass->finalize = ufo_horizontal_interpolate_task_finalize;
node_class->equal = ufo_horizontal_interpolate_task_equal_real;
+ properties[PROP_USE_ONESIDED_GRADIENT] =
+ g_param_spec_boolean ("use-one-sided-gradient",
+ "In case the mask spans all the way to the border, use two points on one side and fill with gradient",
+ "In case the mask spans all the way to the border, use two points on one side and fill with gradient",
+ TRUE, G_PARAM_READWRITE);
+
+ for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
+ g_object_class_install_property (oclass, i, properties[i]);
+
g_type_class_add_private (oclass, sizeof(UfoHorizontalInterpolateTaskPrivate));
}
@@ -163,4 +221,5 @@ static void
ufo_horizontal_interpolate_task_init(UfoHorizontalInterpolateTask *self)
{
self->priv = UFO_HORIZONTAL_INTERPOLATE_TASK_GET_PRIVATE(self);
+ self->priv->use_onesided_gradient = TRUE;
}