From 613273cbf1cbf681d19d4649c86b593aea7f2df3 Mon Sep 17 00:00:00 2001 From: Tomas Farago Date: Fri, 9 Aug 2019 11:20:19 +0200 Subject: Add FindLargeSpots --- src/CMakeLists.txt | 5 + src/kernels/meson.build | 1 + src/kernels/morphology.cl | 103 +++++++++ src/meson.build | 14 ++ src/ufo-find-large-spots-task.c | 447 ++++++++++++++++++++++++++++++++++++++++ src/ufo-find-large-spots-task.h | 53 +++++ 6 files changed, 623 insertions(+) create mode 100644 src/kernels/morphology.cl create mode 100644 src/ufo-find-large-spots-task.c create mode 100644 src/ufo-find-large-spots-task.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f69f19..14e6f52 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,7 @@ set(ufofilter_SRCS ufo-dump-ring-task.c ufo-duplicate-task.c ufo-filter-task.c + ufo-find-large-spots-task.c ufo-flatten-task.c ufo-flatten-inplace-task.c ufo-flat-field-correct-task.c @@ -131,6 +132,10 @@ set(non_local_means_aux_SRCS common/ufo-math.c common/ufo-common.c) +set(find_large_spots_aux_SRCS + common/ufo-math.c + common/ufo-common.c) + file(GLOB ufofilter_KERNELS "kernels/*.cl") #}}} #{{{ Variables diff --git a/src/kernels/meson.build b/src/kernels/meson.build index 4126c27..f8a685c 100644 --- a/src/kernels/meson.build +++ b/src/kernels/meson.build @@ -27,6 +27,7 @@ kernel_files = [ 'mask.cl', 'median.cl', 'metaballs.cl', + 'morphology.cl', 'nlm.cl', 'ordfilt.cl', 'opencl.cl', diff --git a/src/kernels/morphology.cl b/src/kernels/morphology.cl new file mode 100644 index 0000000..2f0c38d --- /dev/null +++ b/src/kernels/morphology.cl @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2011-2019 Karlsruhe Institute of Technology + * + * This file is part of Ufo. + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +kernel void +set_abs_above_threshold (global float *input, + global float *output, + const float threshold) +{ + int index = get_global_id (1) * get_global_size (0) + get_global_id (0); + + output[index] = fabs (input[index]) > threshold ? 1 : 0; +} + +kernel void +set_to_ones (global float *values) +{ + int x = get_global_id (0) + 1; + int y = get_global_id (1) + 1; + int width = get_global_size (0) + 2; + + values[y * width + x] = 1; +} + +kernel void +grow_region_above_threshold (global float *input, + global float *visited, + global float *output, + global int *counter, + const float threshold) +{ + int x = get_global_id (0) + 1; + int y = get_global_id (1) + 1; + int width = get_global_size (0) + 2; + int offset = y * width; + int index = offset + x; + float value, diff = 0.0f, maximum = 0.0f; + int dxy; + + if (visited[index]) { + return; + } + value = input[index]; + + for (dxy = -1; dxy < 2; dxy += 2) { + /* Check x +/- 1 */ + if (visited[offset + x + dxy]) { + diff = fabs (value - input[offset + x + dxy]); + if (diff > maximum) { + maximum = diff; + } + } + /* Check y +/- 1 */ + if (visited[(y + dxy) * width + x]) { + diff = fabs (value - input[(y + dxy) * width + x]); + if (diff > maximum) { + maximum = diff; + } + } + } + if (maximum > threshold) { + output[index] = 1; + atomic_inc (counter); + } +} + +kernel void +fill_holes (global int *input, + global int *visited, + global int *output, + global int *counter) +{ + int x = get_global_id (0) + 1; + int y = get_global_id (1) + 1; + int width = get_global_size (0) + 2; + int offset = y * width; + int index = offset + x; + + if (!visited[index] || input[index]) { + return; + } + + if (!(visited[offset + x - 1] && visited[offset + x + 1] && visited[(y - 1) * width + x] && visited[(y + 1) * width + x])) { + output[index] = 0; + atomic_inc (counter); + } +} + diff --git a/src/meson.build b/src/meson.build index 4cd4bdc..510d119 100644 --- a/src/meson.build +++ b/src/meson.build @@ -184,6 +184,20 @@ shared_module('nonlocalmeans', install_dir: plugin_install_dir, ) +# find large spots + +shared_module('findlargespots', + sources: [ + 'ufo-find-large-spots-task.c', + 'common/ufo-math.c', + 'common/ufo-common.c', + ], + dependencies: deps, + name_prefix: 'libufofilter', + install: true, + install_dir: plugin_install_dir, +) + # fft plugins have_clfft = clfft_dep.found() diff --git a/src/ufo-find-large-spots-task.c b/src/ufo-find-large-spots-task.c new file mode 100644 index 0000000..d9b055a --- /dev/null +++ b/src/ufo-find-large-spots-task.c @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2011-2019 Karlsruhe Institute of Technology + * + * This file is part of Ufo. + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "ufo-find-large-spots-task.h" +#include "common/ufo-addressing.h" +#include "common/ufo-common.h" + + +struct _UfoFindLargeSpotsTaskPrivate { + gfloat spot_threshold; + gfloat grow_threshold; + cl_context context; + cl_kernel set_ones_kernel, set_threshold_kernel, grow_kernel, holes_kernel, convolution_kernel, sum_kernel; + cl_sampler sampler; + cl_mem aux_mem[2], counter_mem; + AddressingMode addressing_mode; +}; + +static void ufo_task_interface_init (UfoTaskIface *iface); + +G_DEFINE_TYPE_WITH_CODE (UfoFindLargeSpotsTask, ufo_find_large_spots_task, UFO_TYPE_TASK_NODE, + G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK, + ufo_task_interface_init)) + +#define UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FIND_LARGE_SPOTS_TASK, UfoFindLargeSpotsTaskPrivate)) + +enum { + PROP_0, + PROP_SPOT_THRESHOLD, + PROP_GROW_THRESHOLD, + PROP_ADDRESSING_MODE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +UfoNode * +ufo_find_large_spots_task_new (void) +{ + return UFO_NODE (g_object_new (UFO_TYPE_FIND_LARGE_SPOTS_TASK, NULL)); +} + +static void +ufo_find_large_spots_task_setup (UfoTask *task, + UfoResources *resources, + GError **error) +{ + cl_int err; + UfoFindLargeSpotsTaskPrivate *priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE (task); + + priv->context = ufo_resources_get_context (resources); + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainContext (priv->context), error); + + priv->set_ones_kernel = ufo_resources_get_kernel (resources, "morphology.cl", "set_to_ones", NULL, error); + priv->set_threshold_kernel = ufo_resources_get_kernel (resources, "morphology.cl", "set_abs_above_threshold", NULL, error); + priv->grow_kernel = ufo_resources_get_kernel (resources, "morphology.cl", "grow_region_above_threshold", NULL, error); + priv->holes_kernel = ufo_resources_get_kernel (resources, "morphology.cl", "fill_holes", NULL, error); + priv->convolution_kernel = ufo_resources_get_kernel (resources, "estimate-noise.cl", "convolve_abs_laplacian_diff", NULL, error); + priv->sum_kernel = ufo_resources_get_kernel (resources, "reductor.cl", "reduce_M_SUM", NULL, error); + for (gint i = 0; i < 2; i++) { + priv->aux_mem[i] = NULL; + } + priv->counter_mem = NULL; + + if (priv->set_ones_kernel) { + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainKernel (priv->set_ones_kernel), error); + } + if (priv->set_threshold_kernel) { + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainKernel (priv->set_threshold_kernel), error); + } + if (priv->grow_kernel) { + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainKernel (priv->grow_kernel), error); + } + if (priv->holes_kernel) { + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainKernel (priv->holes_kernel), error); + } + if (priv->convolution_kernel) { + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainKernel (priv->convolution_kernel), error); + } + if (priv->sum_kernel) { + UFO_RESOURCES_CHECK_SET_AND_RETURN (clRetainKernel (priv->sum_kernel), error); + } + priv->sampler = clCreateSampler (priv->context, + (cl_bool) TRUE, + priv->addressing_mode, + CL_FILTER_NEAREST, + &err); + UFO_RESOURCES_CHECK_CLERR (err); +} + +static void +ufo_find_large_spots_task_get_requisition (UfoTask *task, + UfoBuffer **inputs, + UfoRequisition *requisition, + GError **error) +{ + cl_int err; + UfoFindLargeSpotsTaskPrivate *priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE (task); + + ufo_buffer_get_requisition (inputs[0], requisition); + + if (!priv->aux_mem[0]) { + for (gint i = 0; i < 2; i++) { + priv->aux_mem[i] = clCreateBuffer (priv->context, + CL_MEM_READ_WRITE, + sizeof (cl_float) * requisition->dims[0] * requisition->dims[1], + NULL, + &err); + UFO_RESOURCES_CHECK_CLERR (err); + } + priv->counter_mem = clCreateBuffer (priv->context, + CL_MEM_READ_WRITE, + sizeof (cl_int), + NULL, + &err); + UFO_RESOURCES_CHECK_CLERR (err); + } +} + +static guint +ufo_find_large_spots_task_get_num_inputs (UfoTask *task) +{ + return 1; +} + +static guint +ufo_find_large_spots_task_get_num_dimensions (UfoTask *task, + guint input) +{ + return 2; +} + +static UfoTaskMode +ufo_find_large_spots_task_get_mode (UfoTask *task) +{ + return UFO_TASK_MODE_PROCESSOR | UFO_TASK_MODE_GPU; +} + +static gboolean +ufo_find_large_spots_task_process (UfoTask *task, + UfoBuffer **inputs, + UfoBuffer *output, + UfoRequisition *requisition) +{ + UfoFindLargeSpotsTaskPrivate *priv; + UfoGpuNode *node; + UfoProfiler *profiler; + GValue *max_work_group_size_gvalue; + gsize max_work_group_size; + cl_command_queue cmd_queue; + cl_mem in_mem; + cl_mem out_mem; + gfloat estimated_sigma; + gsize global_size[2]; + gint counter = 1, fill_pattern = 0; + + priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE (task); + node = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task))); + cmd_queue = ufo_gpu_node_get_cmd_queue (node); + out_mem = ufo_buffer_get_device_array (output, cmd_queue); + profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task)); + global_size[0] = requisition->dims[0] - 2; + global_size[1] = requisition->dims[1] - 2; + + if (priv->grow_threshold <= 0.0f) { + max_work_group_size_gvalue = ufo_gpu_node_get_info (node, UFO_GPU_NODE_INFO_MAX_WORK_GROUP_SIZE); + max_work_group_size = g_value_get_ulong (max_work_group_size_gvalue); + g_value_unset (max_work_group_size_gvalue); + in_mem = ufo_buffer_get_device_image (inputs[0], cmd_queue); + estimated_sigma = ufo_common_estimate_sigma (priv->convolution_kernel, + priv->sum_kernel, + cmd_queue, + priv->sampler, + profiler, + in_mem, + out_mem, + max_work_group_size, + requisition->dims); + /* IF not specified, make grow_threshold FWTM of the assumed noise normal distribution. */ + priv->grow_threshold = 4.29 * estimated_sigma; + g_debug ("Estimated sigma: %g", estimated_sigma); + } + in_mem = ufo_buffer_get_device_array (inputs[0], cmd_queue); + + /* First set the mask to 1 where spot_threshold is exceeded */ + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->set_threshold_kernel, 0, sizeof (cl_mem), &in_mem)); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->set_threshold_kernel, 1, sizeof (cl_mem), &priv->aux_mem[0])); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->set_threshold_kernel, 2, sizeof (cl_int), &priv->spot_threshold)); + ufo_profiler_call (profiler, cmd_queue, priv->set_threshold_kernel, 2, requisition->dims, NULL); + UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyBuffer (cmd_queue, + priv->aux_mem[0], + priv->aux_mem[1], + 0, 0, sizeof (cl_float) * requisition->dims[0] * requisition->dims[1], + 0, NULL, NULL)); + + while (counter) { + /* Grow the seeds until the difference between surrouding pixels is less + * than grow_threshold. */ + /* Reset counter */ + UFO_RESOURCES_CHECK_CLERR (clEnqueueFillBuffer (cmd_queue, priv->counter_mem, &fill_pattern, sizeof (cl_int), + 0, sizeof (cl_int), 0, NULL, NULL)); + + /* Grow region */ + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->grow_kernel, 0, sizeof (cl_mem), &in_mem)); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->grow_kernel, 1, sizeof (cl_mem), &priv->aux_mem[0])); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->grow_kernel, 2, sizeof (cl_mem), &priv->aux_mem[1])); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->grow_kernel, 3, sizeof (cl_mem), &priv->counter_mem)); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->grow_kernel, 4, sizeof (cl_int), &priv->grow_threshold)); + ufo_profiler_call (profiler, cmd_queue, priv->grow_kernel, 2, global_size, NULL); + /* New visited is the last grown. */ + UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyBuffer (cmd_queue, + priv->aux_mem[1], + priv->aux_mem[0], + 0, 0, sizeof (cl_float) * requisition->dims[0] * requisition->dims[1], + 0, NULL, NULL)); + UFO_RESOURCES_CHECK_CLERR (clEnqueueReadBuffer (cmd_queue, + priv->counter_mem, + CL_TRUE, + 0, + sizeof (cl_int), + &counter, + 0, NULL, NULL)); + } + + /* Initialize resulting mask to ones except borders and pixels where current + * mask is set. This will serve for growing the boundary towards the center, + * i.e. filling holes. From now on, aux_mem[0] is the fixed mask with holes + * and aux_mem[1] with out_mem are the result/visited pair. + */ + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->set_ones_kernel, 0, sizeof (cl_mem), &priv->aux_mem[1])); + ufo_profiler_call (profiler, cmd_queue, priv->set_ones_kernel, 2, global_size, NULL); + UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyBuffer (cmd_queue, + priv->aux_mem[1], + out_mem, + 0, 0, sizeof (cl_float) * requisition->dims[0] * requisition->dims[1], + 0, NULL, NULL)); + + counter = 1; + while (counter) { + /* Fill holes by progressing from the edges towards the center and + * taking into account the pre-computed mask. */ + /* Reset counter */ + UFO_RESOURCES_CHECK_CLERR (clEnqueueFillBuffer (cmd_queue, priv->counter_mem, &fill_pattern, sizeof (cl_int), + 0, sizeof (cl_int), 0, NULL, NULL)); + + /* Grow region towards the center */ + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->holes_kernel, 0, sizeof (cl_mem), &priv->aux_mem[0])); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->holes_kernel, 1, sizeof (cl_mem), &priv->aux_mem[1])); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->holes_kernel, 2, sizeof (cl_mem), &out_mem)); + UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->holes_kernel, 3, sizeof (cl_mem), &priv->counter_mem)); + ufo_profiler_call (profiler, cmd_queue, priv->holes_kernel, 2, global_size, NULL); + /* New visited is the last grown. */ + UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyBuffer (cmd_queue, + out_mem, + priv->aux_mem[1], + 0, 0, sizeof (cl_float) * requisition->dims[0] * requisition->dims[1], + 0, NULL, NULL)); + UFO_RESOURCES_CHECK_CLERR (clEnqueueReadBuffer (cmd_queue, + priv->counter_mem, + CL_TRUE, + 0, + sizeof (cl_int), + &counter, + 0, NULL, NULL)); + } + + return TRUE; +} + + +static void +ufo_find_large_spots_task_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + UfoFindLargeSpotsTaskPrivate *priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE (object); + + switch (property_id) { + case PROP_SPOT_THRESHOLD: + priv->spot_threshold = g_value_get_float (value); + break; + case PROP_GROW_THRESHOLD: + priv->grow_threshold = g_value_get_float (value); + break; + case PROP_ADDRESSING_MODE: + priv->addressing_mode = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +ufo_find_large_spots_task_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + UfoFindLargeSpotsTaskPrivate *priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE (object); + + switch (property_id) { + case PROP_SPOT_THRESHOLD: + g_value_set_float (value, priv->spot_threshold); + break; + case PROP_GROW_THRESHOLD: + g_value_set_float (value, priv->grow_threshold); + break; + case PROP_ADDRESSING_MODE: + g_value_set_enum (value, priv->addressing_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +ufo_find_large_spots_task_finalize (GObject *object) +{ + UfoFindLargeSpotsTaskPrivate *priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE (object); + + if (priv->set_ones_kernel) { + UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->set_ones_kernel)); + priv->set_ones_kernel = NULL; + } + if (priv->set_threshold_kernel) { + UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->set_threshold_kernel)); + priv->set_threshold_kernel = NULL; + } + if (priv->grow_kernel) { + UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->grow_kernel)); + priv->grow_kernel = NULL; + } + if (priv->holes_kernel) { + UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->holes_kernel)); + priv->holes_kernel = NULL; + } + if (priv->convolution_kernel) { + UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->convolution_kernel)); + priv->convolution_kernel = NULL; + } + if (priv->sum_kernel) { + UFO_RESOURCES_CHECK_CLERR (clReleaseKernel (priv->sum_kernel)); + priv->sum_kernel = NULL; + } + if (priv->sampler) { + UFO_RESOURCES_CHECK_CLERR (clReleaseSampler (priv->sampler)); + priv->sampler = NULL; + } + for (gint i = 0; i < 2; i++) { + if (priv->aux_mem[i]) { + UFO_RESOURCES_CHECK_CLERR (clReleaseMemObject (priv->aux_mem[i])); + priv->aux_mem[i] = NULL; + } + } + if (priv->counter_mem) { + UFO_RESOURCES_CHECK_CLERR (clReleaseMemObject (priv->counter_mem)); + priv->counter_mem = NULL; + } + if (priv->context) { + UFO_RESOURCES_CHECK_CLERR (clReleaseContext (priv->context)); + priv->context = NULL; + } + + G_OBJECT_CLASS (ufo_find_large_spots_task_parent_class)->finalize (object); +} + +static void +ufo_task_interface_init (UfoTaskIface *iface) +{ + iface->setup = ufo_find_large_spots_task_setup; + iface->get_num_inputs = ufo_find_large_spots_task_get_num_inputs; + iface->get_num_dimensions = ufo_find_large_spots_task_get_num_dimensions; + iface->get_mode = ufo_find_large_spots_task_get_mode; + iface->get_requisition = ufo_find_large_spots_task_get_requisition; + iface->process = ufo_find_large_spots_task_process; +} + +static void +ufo_find_large_spots_task_class_init (UfoFindLargeSpotsTaskClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + oclass->set_property = ufo_find_large_spots_task_set_property; + oclass->get_property = ufo_find_large_spots_task_get_property; + oclass->finalize = ufo_find_large_spots_task_finalize; + + properties[PROP_SPOT_THRESHOLD] = + g_param_spec_float ("spot-threshold", + "Pixels with grey value larger than this are considered as spots", + "Pixels with grey value larger than this are considered as spots", + 0.0f, G_MAXFLOAT, 0.0f, + G_PARAM_READWRITE); + + properties[PROP_GROW_THRESHOLD] = + g_param_spec_float ("grow-threshold", + "Spot growing threshold", + "Spot growing threshold", + 0.0f, G_MAXFLOAT, 0.0f, + G_PARAM_READWRITE); + + properties[PROP_ADDRESSING_MODE] = + g_param_spec_enum ("addressing-mode", + "Outlier treatment (\"none\", \"clamp\", \"clamp_to_edge\", \"repeat\", \"mirrored_repeat\")", + "Outlier treatment (\"none\", \"clamp\", \"clamp_to_edge\", \"repeat\", \"mirrored_repeat\")", + g_enum_register_static ("find_addressing_mode", addressing_values), + CL_ADDRESS_MIRRORED_REPEAT, + 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(UfoFindLargeSpotsTaskPrivate)); +} + +static void +ufo_find_large_spots_task_init(UfoFindLargeSpotsTask *self) +{ + self->priv = UFO_FIND_LARGE_SPOTS_TASK_GET_PRIVATE(self); + self->priv->spot_threshold = 0.0f; + self->priv->grow_threshold = 0.0f; + self->priv->addressing_mode = CL_ADDRESS_MIRRORED_REPEAT; +} diff --git a/src/ufo-find-large-spots-task.h b/src/ufo-find-large-spots-task.h new file mode 100644 index 0000000..6afbfe0 --- /dev/null +++ b/src/ufo-find-large-spots-task.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011-2013 Karlsruhe Institute of Technology + * + * This file is part of Ufo. + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __UFO_FIND_LARGE_SPOTS_TASK_H +#define __UFO_FIND_LARGE_SPOTS_TASK_H + +#include + +G_BEGIN_DECLS + +#define UFO_TYPE_FIND_LARGE_SPOTS_TASK (ufo_find_large_spots_task_get_type()) +#define UFO_FIND_LARGE_SPOTS_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_FIND_LARGE_SPOTS_TASK, UfoFindLargeSpotsTask)) +#define UFO_IS_FIND_LARGE_SPOTS_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_FIND_LARGE_SPOTS_TASK)) +#define UFO_FIND_LARGE_SPOTS_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_FIND_LARGE_SPOTS_TASK, UfoFindLargeSpotsTaskClass)) +#define UFO_IS_FIND_LARGE_SPOTS_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_FIND_LARGE_SPOTS_TASK)) +#define UFO_FIND_LARGE_SPOTS_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_FIND_LARGE_SPOTS_TASK, UfoFindLargeSpotsTaskClass)) + +typedef struct _UfoFindLargeSpotsTask UfoFindLargeSpotsTask; +typedef struct _UfoFindLargeSpotsTaskClass UfoFindLargeSpotsTaskClass; +typedef struct _UfoFindLargeSpotsTaskPrivate UfoFindLargeSpotsTaskPrivate; + +struct _UfoFindLargeSpotsTask { + UfoTaskNode parent_instance; + + UfoFindLargeSpotsTaskPrivate *priv; +}; + +struct _UfoFindLargeSpotsTaskClass { + UfoTaskNodeClass parent_class; +}; + +UfoNode *ufo_find_large_spots_task_new (void); +GType ufo_find_large_spots_task_get_type (void); + +G_END_DECLS + +#endif -- cgit v1.2.1