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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. G_DEFINE_TYPE_WITH_CODE (UfoEdf3dWriterTask, ufo_edf_3d_writer_task, UFO_TYPE_TASK_NODE,
  34. G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
  35. ufo_task_interface_init))
  36. #define UFO_EDF_3D_WRITER_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_EDF_3D_WRITER_TASK, UfoEdf3dWriterTaskPrivate))
  37. enum {
  38. PROP_0,
  39. PROP_FILENAME,
  40. N_PROPERTIES
  41. };
  42. static GParamSpec *properties[N_PROPERTIES] = { NULL, };
  43. UfoNode *
  44. ufo_edf_3d_writer_task_new (void)
  45. {
  46. return UFO_NODE (g_object_new (UFO_TYPE_EDF_3D_WRITER_TASK, NULL));
  47. }
  48. static gchar *
  49. build_template (const gchar *format)
  50. {
  51. gchar *template;
  52. gchar *percent;
  53. template = g_strdup (format);
  54. percent = g_strstr_len (template, -1, "%");
  55. if (percent != NULL) {
  56. percent++;
  57. while (*percent) {
  58. if (*percent == '%')
  59. *percent = '_';
  60. percent++;
  61. }
  62. }
  63. else {
  64. g_warning ("Specifier %%i not found. Appending it.");
  65. g_free (template);
  66. template = g_strconcat (format, "%i", NULL);
  67. }
  68. return template;
  69. }
  70. static void
  71. ufo_edf_3d_writer_task_setup (UfoTask *task,
  72. UfoResources *resources,
  73. GError **error)
  74. {
  75. UfoEdf3dWriterTaskPrivate *priv;
  76. priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (task);
  77. priv->template = build_template (priv->filename);
  78. }
  79. static void
  80. ufo_edf_3d_writer_task_get_requisition (UfoTask *task,
  81. UfoBuffer **inputs,
  82. UfoRequisition *requisition)
  83. {
  84. requisition->n_dims = 0;
  85. }
  86. static guint
  87. ufo_edf_3d_writer_task_get_num_inputs (UfoTask *task)
  88. {
  89. return 1;
  90. }
  91. static guint
  92. ufo_edf_3d_writer_task_get_num_dimensions (UfoTask *task,
  93. guint input)
  94. {
  95. g_return_val_if_fail (input == 0, 0);
  96. return 3;
  97. }
  98. static UfoTaskMode
  99. ufo_edf_3d_writer_task_get_mode (UfoTask *task)
  100. {
  101. return UFO_TASK_MODE_PROCESSOR | UFO_TASK_MODE_CPU;
  102. }
  103. static gboolean
  104. write_header (FILE *fp, UfoBuffer *buffer)
  105. {
  106. UfoRequisition req;
  107. gchar *header;
  108. const gsize length = 512;
  109. gboolean result = TRUE;
  110. ufo_buffer_get_requisition (buffer, &req);
  111. header = g_strnfill (length, ' ');
  112. g_snprintf (header, length,
  113. "{\nByteOrder = LowByteFirst;\nDataType = FloatValue;\nDim_1 = %zu;\nDim_2 = %zu;\nDim_3 = %zu;\nSize = %zu;\n",
  114. req.dims[0], req.dims[1], req.dims[2],
  115. req.dims[0] * req.dims[1] * req.dims[2] * sizeof(gfloat));
  116. header[510] = '}';
  117. header[511] = '\x0A';
  118. result = fwrite (header, sizeof(gchar), length, fp) == length;
  119. g_free (header);
  120. return result;
  121. }
  122. static gboolean
  123. write_body (FILE *fp, UfoBuffer *buffer)
  124. {
  125. gfloat *data;
  126. gsize size;
  127. data = ufo_buffer_get_host_array (buffer, NULL);
  128. size = ufo_buffer_get_size (buffer);
  129. return fwrite (data, 1, size, fp) == size;
  130. }
  131. static gboolean
  132. ufo_edf_3d_writer_task_process (UfoTask *task,
  133. UfoBuffer **inputs,
  134. UfoBuffer *output,
  135. UfoRequisition *requisition)
  136. {
  137. UfoEdf3dWriterTaskPrivate *priv;
  138. UfoProfiler *profiler;
  139. gchar *filename;
  140. FILE *fp;
  141. priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (UFO_EDF_3D_WRITER_TASK (task));
  142. profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task));
  143. filename = g_strdup_printf (priv->template, priv->counter);
  144. ufo_profiler_start (profiler, UFO_PROFILER_TIMER_IO);
  145. fp = fopen (filename, "wb");
  146. if (!write_header (fp, inputs[0]))
  147. goto error_cleanup;
  148. if (!write_body (fp, inputs[0]))
  149. goto error_cleanup;
  150. fclose (fp);
  151. ufo_profiler_stop (profiler, UFO_PROFILER_TIMER_IO);
  152. g_free (filename);
  153. priv->counter++;
  154. return TRUE;
  155. error_cleanup:
  156. g_warning ("Could not write EDF data");
  157. fclose (fp);
  158. g_free (filename);
  159. return FALSE;
  160. }
  161. static void
  162. ufo_edf_3d_writer_task_set_property (GObject *object,
  163. guint property_id,
  164. const GValue *value,
  165. GParamSpec *pspec)
  166. {
  167. UfoEdf3dWriterTaskPrivate *priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
  168. switch (property_id) {
  169. case PROP_FILENAME:
  170. g_free (priv->filename);
  171. priv->filename = g_value_dup_string (value);
  172. break;
  173. default:
  174. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  175. break;
  176. }
  177. }
  178. static void
  179. ufo_edf_3d_writer_task_get_property (GObject *object,
  180. guint property_id,
  181. GValue *value,
  182. GParamSpec *pspec)
  183. {
  184. UfoEdf3dWriterTaskPrivate *priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
  185. switch (property_id) {
  186. case PROP_FILENAME:
  187. g_value_set_string (value, priv->filename);
  188. break;
  189. default:
  190. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  191. break;
  192. }
  193. }
  194. static void
  195. ufo_edf_3d_writer_task_finalize (GObject *object)
  196. {
  197. UfoEdf3dWriterTaskPrivate *priv;
  198. priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
  199. g_free (priv->filename);
  200. g_free (priv->template);
  201. G_OBJECT_CLASS (ufo_edf_3d_writer_task_parent_class)->finalize (object);
  202. }
  203. static void
  204. ufo_task_interface_init (UfoTaskIface *iface)
  205. {
  206. iface->setup = ufo_edf_3d_writer_task_setup;
  207. iface->get_num_inputs = ufo_edf_3d_writer_task_get_num_inputs;
  208. iface->get_num_dimensions = ufo_edf_3d_writer_task_get_num_dimensions;
  209. iface->get_mode = ufo_edf_3d_writer_task_get_mode;
  210. iface->get_requisition = ufo_edf_3d_writer_task_get_requisition;
  211. iface->process = ufo_edf_3d_writer_task_process;
  212. }
  213. static void
  214. ufo_edf_3d_writer_task_class_init (UfoEdf3dWriterTaskClass *klass)
  215. {
  216. GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  217. gobject_class->set_property = ufo_edf_3d_writer_task_set_property;
  218. gobject_class->get_property = ufo_edf_3d_writer_task_get_property;
  219. gobject_class->finalize = ufo_edf_3d_writer_task_finalize;
  220. properties[PROP_FILENAME] =
  221. g_param_spec_string ("filename",
  222. "Filename format string",
  223. "Format string of the path and filename. If multiple files are written it must contain a '%i' specifier denoting the current count",
  224. "./output-%05i.edf",
  225. G_PARAM_READWRITE);
  226. for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
  227. g_object_class_install_property (gobject_class, i, properties[i]);
  228. g_type_class_add_private (gobject_class, sizeof(UfoEdf3dWriterTaskPrivate));
  229. }
  230. static void
  231. ufo_edf_3d_writer_task_init(UfoEdf3dWriterTask *self)
  232. {
  233. self->priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE(self);
  234. self->priv->filename = g_strdup ("./output-%05i.edf");
  235. self->priv->template = NULL;
  236. self->priv->counter = 0;
  237. }