ufo-edf-3d-writer-task.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Copyright (C) 2011-2013 Karlsruhe Institute of Technology
  3. *
  4. * This file is part of Ufo.
  5. *
  6. * This library is free software: you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation, either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <gmodule.h>
  20. #include <stdio.h>
  21. #include "ufo-edf-3d-writer-task.h"
  22. /**
  23. * SECTION:ufo-edf-3d-writer-task
  24. * @Short_description: Write 3D EDF files
  25. * @Title: edf-3d-writer
  26. */
  27. struct _UfoEdf3dWriterTaskPrivate {
  28. gchar *filename;
  29. gchar *template;
  30. guint counter;
  31. };
  32. static void ufo_task_interface_init (UfoTaskIface *iface);
  33. static void ufo_cpu_task_interface_init (UfoCpuTaskIface *iface);
  34. G_DEFINE_TYPE_WITH_CODE (UfoEdf3dWriterTask, ufo_edf_3d_writer_task, UFO_TYPE_TASK_NODE,
  35. G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
  36. ufo_task_interface_init)
  37. G_IMPLEMENT_INTERFACE (UFO_TYPE_CPU_TASK,
  38. ufo_cpu_task_interface_init))
  39. #define UFO_EDF_3D_WRITER_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_EDF_3D_WRITER_TASK, UfoEdf3dWriterTaskPrivate))
  40. enum {
  41. PROP_0,
  42. PROP_FILENAME,
  43. N_PROPERTIES
  44. };
  45. static GParamSpec *properties[N_PROPERTIES] = { NULL, };
  46. UfoNode *
  47. ufo_edf_3d_writer_task_new (void)
  48. {
  49. return UFO_NODE (g_object_new (UFO_TYPE_EDF_3D_WRITER_TASK, NULL));
  50. }
  51. static gchar *
  52. build_template (const gchar *format)
  53. {
  54. gchar *template;
  55. gchar *percent;
  56. template = g_strdup (format);
  57. percent = g_strstr_len (template, -1, "%");
  58. if (percent != NULL) {
  59. percent++;
  60. while (*percent) {
  61. if (*percent == '%')
  62. *percent = '_';
  63. percent++;
  64. }
  65. }
  66. else {
  67. g_warning ("Specifier %%i not found. Appending it.");
  68. g_free (template);
  69. template = g_strconcat (format, "%i", NULL);
  70. }
  71. return template;
  72. }
  73. static void
  74. ufo_edf_3d_writer_task_setup (UfoTask *task,
  75. UfoResources *resources,
  76. GError **error)
  77. {
  78. UfoEdf3dWriterTaskPrivate *priv;
  79. priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (task);
  80. priv->template = build_template (priv->filename);
  81. }
  82. static void
  83. ufo_edf_3d_writer_task_get_requisition (UfoTask *task,
  84. UfoBuffer **inputs,
  85. UfoRequisition *requisition)
  86. {
  87. requisition->n_dims = 0;
  88. }
  89. static void
  90. ufo_edf_3d_writer_task_get_structure (UfoTask *task,
  91. guint *n_inputs,
  92. UfoInputParam **in_params,
  93. UfoTaskMode *mode)
  94. {
  95. *mode = UFO_TASK_MODE_PROCESSOR;
  96. *n_inputs = 1;
  97. *in_params = g_new0 (UfoInputParam, 1);
  98. (*in_params)[0].n_dims = 3;
  99. }
  100. static gboolean
  101. write_header (FILE *fp, UfoBuffer *buffer)
  102. {
  103. UfoRequisition req;
  104. gchar *header;
  105. const gsize length = 512;
  106. gboolean result = TRUE;
  107. ufo_buffer_get_requisition (buffer, &req);
  108. header = g_strnfill (length, ' ');
  109. g_snprintf (header, length,
  110. "{\nByteOrder = LowByteFirst;\nDataType = FloatValue;\nDim_1 = %zu;\nDim_2 = %zu;\nDim_3 = %zu;\nSize = %zu;\n",
  111. req.dims[0], req.dims[1], req.dims[2],
  112. req.dims[0] * req.dims[1] * req.dims[2] * sizeof(gfloat));
  113. header[510] = '}';
  114. header[511] = '\x0A';
  115. result = fwrite (header, sizeof(gchar), length, fp) == length;
  116. g_free (header);
  117. return result;
  118. }
  119. static gboolean
  120. write_body (FILE *fp, UfoBuffer *buffer)
  121. {
  122. gfloat *data;
  123. gsize size;
  124. data = ufo_buffer_get_host_array (buffer, NULL);
  125. size = ufo_buffer_get_size (buffer);
  126. return fwrite (data, 1, size, fp) == size;
  127. }
  128. static gboolean
  129. ufo_edf_3d_writer_task_process (UfoCpuTask *task,
  130. UfoBuffer **inputs,
  131. UfoBuffer *output,
  132. UfoRequisition *requisition)
  133. {
  134. UfoEdf3dWriterTaskPrivate *priv;
  135. UfoProfiler *profiler;
  136. gchar *filename;
  137. FILE *fp;
  138. priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (UFO_EDF_3D_WRITER_TASK (task));
  139. profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task));
  140. filename = g_strdup_printf (priv->template, priv->counter);
  141. ufo_profiler_start (profiler, UFO_PROFILER_TIMER_IO);
  142. fp = fopen (filename, "wb");
  143. if (!write_header (fp, inputs[0]))
  144. goto error_cleanup;
  145. if (!write_body (fp, inputs[0]))
  146. goto error_cleanup;
  147. fclose (fp);
  148. ufo_profiler_stop (profiler, UFO_PROFILER_TIMER_IO);
  149. g_free (filename);
  150. priv->counter++;
  151. return TRUE;
  152. error_cleanup:
  153. g_warning ("Could not write EDF data");
  154. fclose (fp);
  155. g_free (filename);
  156. return FALSE;
  157. }
  158. static void
  159. ufo_edf_3d_writer_task_set_property (GObject *object,
  160. guint property_id,
  161. const GValue *value,
  162. GParamSpec *pspec)
  163. {
  164. UfoEdf3dWriterTaskPrivate *priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
  165. switch (property_id) {
  166. case PROP_FILENAME:
  167. g_free (priv->filename);
  168. priv->filename = g_value_dup_string (value);
  169. break;
  170. default:
  171. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  172. break;
  173. }
  174. }
  175. static void
  176. ufo_edf_3d_writer_task_get_property (GObject *object,
  177. guint property_id,
  178. GValue *value,
  179. GParamSpec *pspec)
  180. {
  181. UfoEdf3dWriterTaskPrivate *priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
  182. switch (property_id) {
  183. case PROP_FILENAME:
  184. g_value_set_string (value, priv->filename);
  185. break;
  186. default:
  187. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  188. break;
  189. }
  190. }
  191. static void
  192. ufo_edf_3d_writer_task_finalize (GObject *object)
  193. {
  194. UfoEdf3dWriterTaskPrivate *priv;
  195. priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
  196. g_free (priv->filename);
  197. g_free (priv->template);
  198. G_OBJECT_CLASS (ufo_edf_3d_writer_task_parent_class)->finalize (object);
  199. }
  200. static void
  201. ufo_task_interface_init (UfoTaskIface *iface)
  202. {
  203. iface->setup = ufo_edf_3d_writer_task_setup;
  204. iface->get_structure = ufo_edf_3d_writer_task_get_structure;
  205. iface->get_requisition = ufo_edf_3d_writer_task_get_requisition;
  206. }
  207. static void
  208. ufo_cpu_task_interface_init (UfoCpuTaskIface *iface)
  209. {
  210. iface->process = ufo_edf_3d_writer_task_process;
  211. }
  212. static void
  213. ufo_edf_3d_writer_task_class_init (UfoEdf3dWriterTaskClass *klass)
  214. {
  215. GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  216. gobject_class->set_property = ufo_edf_3d_writer_task_set_property;
  217. gobject_class->get_property = ufo_edf_3d_writer_task_get_property;
  218. gobject_class->finalize = ufo_edf_3d_writer_task_finalize;
  219. properties[PROP_FILENAME] =
  220. g_param_spec_string ("filename",
  221. "Filename format string",
  222. "Format string of the path and filename. If multiple files are written it must contain a '%i' specifier denoting the current count",
  223. "./output-%05i.edf",
  224. G_PARAM_READWRITE);
  225. for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
  226. g_object_class_install_property (gobject_class, i, properties[i]);
  227. g_type_class_add_private (gobject_class, sizeof(UfoEdf3dWriterTaskPrivate));
  228. }
  229. static void
  230. ufo_edf_3d_writer_task_init(UfoEdf3dWriterTask *self)
  231. {
  232. self->priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE(self);
  233. self->priv->filename = g_strdup ("./output-%05i.edf");
  234. self->priv->template = NULL;
  235. self->priv->counter = 0;
  236. }