ufo-filter-lamino-ramp.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #include <gmodule.h>
  2. #ifdef __APPLE__
  3. #include <OpenCL/cl.h>
  4. #else
  5. #include <CL/cl.h>
  6. #endif
  7. #include <ufo/ufo-resource-manager.h>
  8. #include <ufo/ufo-filter-source.h>
  9. #include <ufo/ufo-buffer.h>
  10. #include "ufo-filter-lamino-ramp.h"
  11. /**
  12. * SECTION:ufo-filter-lamino-ramp
  13. * @Short_description:
  14. * @Title: laminoramp
  15. *
  16. * Detailed description.
  17. */
  18. struct _UfoFilterLaminoRampPrivate {
  19. // filter extent
  20. guint width; // is pow of 2
  21. guint fill_width;
  22. guint height;
  23. // laminographic angle
  24. float theta;
  25. // pixel resolution (in um)
  26. float tau;
  27. cl_kernel kernel_cf;
  28. gboolean done;
  29. };
  30. G_DEFINE_TYPE(UfoFilterLaminoRamp, ufo_filter_lamino_ramp, UFO_TYPE_FILTER_SOURCE)
  31. #define UFO_FILTER_LAMINO_RAMP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_LAMINO_RAMP, UfoFilterLaminoRampPrivate))
  32. enum {
  33. PROP_0,
  34. PROP_WIDTH,
  35. PROP_FILL_WIDTH,
  36. PROP_HEIGHT,
  37. PROP_THETA,
  38. PROP_TAU,
  39. N_PROPERTIES
  40. };
  41. static GParamSpec *lamino_ramp_properties[N_PROPERTIES] = { NULL, };
  42. static int
  43. is_power_of_two (guint x)
  44. {
  45. return ((x != 0) && !(x & (x - 1)));
  46. }
  47. static void
  48. ufo_filter_lamino_ramp_initialize (UfoFilterSource *filter, guint **dim_sizes, GError **error)
  49. {
  50. UfoFilterLaminoRampPrivate *priv = UFO_FILTER_LAMINO_RAMP_GET_PRIVATE(filter);
  51. UfoResourceManager *manager = ufo_filter_get_resource_manager(UFO_FILTER(filter));
  52. GError *tmp_error = NULL;
  53. priv->kernel_cf = ufo_resource_manager_get_kernel(manager, "lamino_ramp.cl", "lamino_ramp_create_filter", &tmp_error);
  54. if (tmp_error != NULL) {
  55. g_propagate_error (error, tmp_error);
  56. return;
  57. }
  58. if (!is_power_of_two (priv->width)) {
  59. g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_INITIALIZATION,
  60. "Filter width `%i` is not a power of two", priv->width);
  61. return;
  62. }
  63. if (!is_power_of_two (priv->height)) {
  64. g_set_error (error, UFO_FILTER_ERROR, UFO_FILTER_ERROR_INITIALIZATION,
  65. "Filter height `%i` is not a power of two", priv->height);
  66. return;
  67. }
  68. dim_sizes[0][0] = priv->width;
  69. dim_sizes[0][1] = priv->height;
  70. }
  71. static gboolean
  72. ufo_filter_lamino_ramp_generate (UfoFilterSource *filter, UfoBuffer *output[], GError **error)
  73. {
  74. g_return_val_if_fail (UFO_IS_FILTER (filter), FALSE);
  75. UfoFilterLaminoRampPrivate *priv = UFO_FILTER_LAMINO_RAMP_GET_PRIVATE (filter);
  76. cl_command_queue cmd_queue = ufo_filter_get_command_queue (UFO_FILTER (filter));
  77. if (priv->done)
  78. return FALSE;
  79. guint width = priv->width;
  80. guint fwidth = priv->fill_width;
  81. guint height = priv->height;
  82. float theta = priv->theta;
  83. float tau = priv->tau;
  84. size_t global_work_size[2] = { (size_t) priv->width, (size_t) priv->height };
  85. cl_kernel kernel = priv->kernel_cf;
  86. cl_mem output_mem = (cl_mem) ufo_buffer_get_device_array(output[0], cmd_queue);
  87. CHECK_OPENCL_ERROR(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *) &output_mem));
  88. CHECK_OPENCL_ERROR(clSetKernelArg(kernel, 1, sizeof(int), &width));
  89. CHECK_OPENCL_ERROR(clSetKernelArg(kernel, 2, sizeof(int), &fwidth));
  90. CHECK_OPENCL_ERROR(clSetKernelArg(kernel, 3, sizeof(int), &height));
  91. CHECK_OPENCL_ERROR(clSetKernelArg(kernel, 4, sizeof(float), &theta));
  92. CHECK_OPENCL_ERROR(clSetKernelArg(kernel, 5, sizeof(float), &tau));
  93. CHECK_OPENCL_ERROR(clEnqueueNDRangeKernel(cmd_queue, kernel,
  94. 2, NULL, global_work_size, NULL,
  95. 0, NULL, NULL));
  96. priv->done = TRUE;
  97. return TRUE;
  98. }
  99. static void
  100. ufo_filter_lamino_ramp_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
  101. {
  102. UfoFilterLaminoRamp *self = UFO_FILTER_LAMINO_RAMP(object);
  103. switch (property_id) {
  104. case PROP_WIDTH:
  105. self->priv->width = g_value_get_uint(value);
  106. break;
  107. case PROP_FILL_WIDTH:
  108. self->priv->fill_width = g_value_get_uint(value);
  109. break;
  110. case PROP_HEIGHT:
  111. self->priv->height = g_value_get_uint(value);
  112. break;
  113. case PROP_THETA:
  114. self->priv->theta = (float) g_value_get_double(value);
  115. break;
  116. case PROP_TAU:
  117. self->priv->tau = (float) g_value_get_double(value);
  118. break;
  119. default:
  120. G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
  121. break;
  122. }
  123. }
  124. static void
  125. ufo_filter_lamino_ramp_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
  126. {
  127. UfoFilterLaminoRamp *self = UFO_FILTER_LAMINO_RAMP(object);
  128. switch (property_id) {
  129. case PROP_WIDTH:
  130. g_value_set_uint(value, self->priv->width);
  131. break;
  132. case PROP_FILL_WIDTH:
  133. g_value_set_uint(value, self->priv->fill_width);
  134. break;
  135. case PROP_HEIGHT:
  136. g_value_set_uint(value, self->priv->height);
  137. break;
  138. case PROP_THETA:
  139. g_value_set_double(value, self->priv->theta);
  140. break;
  141. case PROP_TAU:
  142. g_value_set_double(value, self->priv->tau);
  143. break;
  144. default:
  145. G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
  146. break;
  147. }
  148. }
  149. static void
  150. ufo_filter_lamino_ramp_class_init(UfoFilterLaminoRampClass *klass)
  151. {
  152. GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
  153. UfoFilterSourceClass *filter_class = UFO_FILTER_SOURCE_CLASS(klass);
  154. gobject_class->set_property = ufo_filter_lamino_ramp_set_property;
  155. gobject_class->get_property = ufo_filter_lamino_ramp_get_property;
  156. filter_class->initialize = ufo_filter_lamino_ramp_initialize;
  157. filter_class->generate = ufo_filter_lamino_ramp_generate;
  158. lamino_ramp_properties[PROP_WIDTH] =
  159. g_param_spec_uint("width",
  160. "Width of the 2D image filter (power of 2)",
  161. "Width of the 2D image filter (power of 2)",
  162. 1, 32768, 1.0,
  163. G_PARAM_READWRITE);
  164. lamino_ramp_properties[PROP_FILL_WIDTH] =
  165. g_param_spec_uint("fwidth",
  166. "Filling width of the 2D image filter",
  167. "Filling width of the 2D image filter",
  168. 1, 32768, 1.0,
  169. G_PARAM_READWRITE);
  170. lamino_ramp_properties[PROP_HEIGHT] =
  171. g_param_spec_uint("height",
  172. "Height of the 2D image filter",
  173. "Height of the 2D image filter",
  174. 1, 16384, 1.0,
  175. G_PARAM_READWRITE);
  176. lamino_ramp_properties[PROP_THETA] =
  177. g_param_spec_double("theta",
  178. "Laminographic angle in radians",
  179. "Resolution (pixel size) in microns",
  180. -4.0 * G_PI, +4.0 * G_PI, 0.0,
  181. G_PARAM_READWRITE);
  182. lamino_ramp_properties[PROP_TAU] =
  183. g_param_spec_double("tau",
  184. "Resolution (pixel size) in microns",
  185. "Resolution (pixel size) in microns",
  186. 0.0, /* minimum */
  187. 100000.0, /* maximum */
  188. 10.0, /* default */
  189. G_PARAM_READWRITE);
  190. g_object_class_install_property(gobject_class, PROP_WIDTH, lamino_ramp_properties[PROP_WIDTH]);
  191. g_object_class_install_property(gobject_class, PROP_FILL_WIDTH, lamino_ramp_properties[PROP_FILL_WIDTH]);
  192. g_object_class_install_property(gobject_class, PROP_HEIGHT, lamino_ramp_properties[PROP_HEIGHT]);
  193. g_object_class_install_property(gobject_class, PROP_THETA, lamino_ramp_properties[PROP_THETA]);
  194. g_object_class_install_property(gobject_class, PROP_TAU, lamino_ramp_properties[PROP_TAU]);
  195. g_type_class_add_private(gobject_class, sizeof(UfoFilterLaminoRampPrivate));
  196. }
  197. static void ufo_filter_lamino_ramp_init(UfoFilterLaminoRamp *self)
  198. {
  199. UfoFilterLaminoRampPrivate *priv = self->priv = UFO_FILTER_LAMINO_RAMP_GET_PRIVATE(self);
  200. UfoOutputParameter output_params[] = {{2}};
  201. priv->width = 4;
  202. priv->fill_width=2;
  203. priv->height = 1;
  204. priv->theta = 0.0;
  205. priv->tau = 10.0;
  206. priv->done = FALSE;
  207. ufo_filter_register_outputs (UFO_FILTER (self), 1, output_params);
  208. }
  209. G_MODULE_EXPORT UfoFilter *
  210. ufo_filter_plugin_new(void)
  211. {
  212. return g_object_new(UFO_TYPE_FILTER_LAMINO_RAMP, NULL);
  213. }