|
@@ -0,0 +1,286 @@
|
|
|
+/*
|
|
|
+ * 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 <http://www.gnu.org/licenses/>.
|
|
|
+ */
|
|
|
+
|
|
|
+#include <gmodule.h>
|
|
|
+#include <stdio.h>
|
|
|
+
|
|
|
+#include "ufo-edf-3d-writer-task.h"
|
|
|
+
|
|
|
+/**
|
|
|
+ * SECTION:ufo-edf-3d-writer-task
|
|
|
+ * @Short_description: Write 3D EDF files
|
|
|
+ * @Title: edf-3d-writer
|
|
|
+ */
|
|
|
+
|
|
|
+struct _UfoEdf3dWriterTaskPrivate {
|
|
|
+ gchar *filename;
|
|
|
+ gchar *template;
|
|
|
+ guint counter;
|
|
|
+};
|
|
|
+
|
|
|
+static void ufo_task_interface_init (UfoTaskIface *iface);
|
|
|
+static void ufo_cpu_task_interface_init (UfoCpuTaskIface *iface);
|
|
|
+
|
|
|
+G_DEFINE_TYPE_WITH_CODE (UfoEdf3dWriterTask, ufo_edf_3d_writer_task, UFO_TYPE_TASK_NODE,
|
|
|
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
|
|
|
+ ufo_task_interface_init)
|
|
|
+ G_IMPLEMENT_INTERFACE (UFO_TYPE_CPU_TASK,
|
|
|
+ ufo_cpu_task_interface_init))
|
|
|
+
|
|
|
+#define UFO_EDF_3D_WRITER_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_EDF_3D_WRITER_TASK, UfoEdf3dWriterTaskPrivate))
|
|
|
+
|
|
|
+enum {
|
|
|
+ PROP_0,
|
|
|
+ PROP_FILENAME,
|
|
|
+ N_PROPERTIES
|
|
|
+};
|
|
|
+
|
|
|
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
|
|
+
|
|
|
+UfoNode *
|
|
|
+ufo_edf_3d_writer_task_new (void)
|
|
|
+{
|
|
|
+ return UFO_NODE (g_object_new (UFO_TYPE_EDF_3D_WRITER_TASK, NULL));
|
|
|
+}
|
|
|
+
|
|
|
+static gchar *
|
|
|
+build_template (const gchar *format)
|
|
|
+{
|
|
|
+ gchar *template;
|
|
|
+ gchar *percent;
|
|
|
+
|
|
|
+ template = g_strdup (format);
|
|
|
+ percent = g_strstr_len (template, -1, "%");
|
|
|
+
|
|
|
+ if (percent != NULL) {
|
|
|
+ percent++;
|
|
|
+
|
|
|
+ while (*percent) {
|
|
|
+ if (*percent == '%')
|
|
|
+ *percent = '_';
|
|
|
+ percent++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ g_warning ("Specifier %%i not found. Appending it.");
|
|
|
+ g_free (template);
|
|
|
+ template = g_strconcat (format, "%i", NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ return template;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_setup (UfoTask *task,
|
|
|
+ UfoResources *resources,
|
|
|
+ GError **error)
|
|
|
+{
|
|
|
+ UfoEdf3dWriterTaskPrivate *priv;
|
|
|
+
|
|
|
+ priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (task);
|
|
|
+ priv->template = build_template (priv->filename);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_get_requisition (UfoTask *task,
|
|
|
+ UfoBuffer **inputs,
|
|
|
+ UfoRequisition *requisition)
|
|
|
+{
|
|
|
+ requisition->n_dims = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_get_structure (UfoTask *task,
|
|
|
+ guint *n_inputs,
|
|
|
+ UfoInputParam **in_params,
|
|
|
+ UfoTaskMode *mode)
|
|
|
+{
|
|
|
+ *mode = UFO_TASK_MODE_PROCESSOR;
|
|
|
+ *n_inputs = 1;
|
|
|
+ *in_params = g_new0 (UfoInputParam, 1);
|
|
|
+ (*in_params)[0].n_dims = 3;
|
|
|
+}
|
|
|
+
|
|
|
+static gboolean
|
|
|
+write_header (FILE *fp, UfoBuffer *buffer)
|
|
|
+{
|
|
|
+ UfoRequisition req;
|
|
|
+ gchar *header;
|
|
|
+ const gsize length = 512;
|
|
|
+ gboolean result = TRUE;
|
|
|
+
|
|
|
+ ufo_buffer_get_requisition (buffer, &req);
|
|
|
+ header = g_strnfill (length, ' ');
|
|
|
+
|
|
|
+ g_snprintf (header, length,
|
|
|
+ "{\nByteOrder = LowByteFirst;\nDataType = FloatValue;\nDim_1 = %zu;\nDim_2 = %zu;\nDim_3 = %zu;\nSize = %zu;\n",
|
|
|
+ req.dims[0], req.dims[1], req.dims[2],
|
|
|
+ req.dims[0] * req.dims[1] * req.dims[2] * sizeof(gfloat));
|
|
|
+
|
|
|
+ header[510] = '}';
|
|
|
+ header[511] = '\x0A';
|
|
|
+
|
|
|
+ result = fwrite (header, sizeof(gchar), length, fp) == length;
|
|
|
+ g_free (header);
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+static gboolean
|
|
|
+write_body (FILE *fp, UfoBuffer *buffer)
|
|
|
+{
|
|
|
+ gfloat *data;
|
|
|
+ gsize size;
|
|
|
+
|
|
|
+ data = ufo_buffer_get_host_array (buffer, NULL);
|
|
|
+ size = ufo_buffer_get_size (buffer);
|
|
|
+ return fwrite (data, 1, size, fp) == size;
|
|
|
+}
|
|
|
+
|
|
|
+static gboolean
|
|
|
+ufo_edf_3d_writer_task_process (UfoCpuTask *task,
|
|
|
+ UfoBuffer **inputs,
|
|
|
+ UfoBuffer *output,
|
|
|
+ UfoRequisition *requisition)
|
|
|
+{
|
|
|
+ UfoEdf3dWriterTaskPrivate *priv;
|
|
|
+ UfoProfiler *profiler;
|
|
|
+ gchar *filename;
|
|
|
+ FILE *fp;
|
|
|
+
|
|
|
+ priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (UFO_EDF_3D_WRITER_TASK (task));
|
|
|
+ profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task));
|
|
|
+ filename = g_strdup_printf (priv->template, priv->counter);
|
|
|
+
|
|
|
+ ufo_profiler_start (profiler, UFO_PROFILER_TIMER_IO);
|
|
|
+ fp = fopen (filename, "wb");
|
|
|
+
|
|
|
+ if (!write_header (fp, inputs[0]))
|
|
|
+ goto error_cleanup;
|
|
|
+
|
|
|
+ if (!write_body (fp, inputs[0]))
|
|
|
+ goto error_cleanup;
|
|
|
+
|
|
|
+ fclose (fp);
|
|
|
+ ufo_profiler_stop (profiler, UFO_PROFILER_TIMER_IO);
|
|
|
+
|
|
|
+ g_free (filename);
|
|
|
+ priv->counter++;
|
|
|
+ return TRUE;
|
|
|
+
|
|
|
+error_cleanup:
|
|
|
+ g_warning ("Could not write EDF data");
|
|
|
+ fclose (fp);
|
|
|
+ g_free (filename);
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_set_property (GObject *object,
|
|
|
+ guint property_id,
|
|
|
+ const GValue *value,
|
|
|
+ GParamSpec *pspec)
|
|
|
+{
|
|
|
+ UfoEdf3dWriterTaskPrivate *priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
|
|
|
+
|
|
|
+ switch (property_id) {
|
|
|
+ case PROP_FILENAME:
|
|
|
+ g_free (priv->filename);
|
|
|
+ priv->filename = g_value_dup_string (value);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_get_property (GObject *object,
|
|
|
+ guint property_id,
|
|
|
+ GValue *value,
|
|
|
+ GParamSpec *pspec)
|
|
|
+{
|
|
|
+ UfoEdf3dWriterTaskPrivate *priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
|
|
|
+
|
|
|
+ switch (property_id) {
|
|
|
+ case PROP_FILENAME:
|
|
|
+ g_value_set_string (value, priv->filename);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_finalize (GObject *object)
|
|
|
+{
|
|
|
+ UfoEdf3dWriterTaskPrivate *priv;
|
|
|
+
|
|
|
+ priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE (object);
|
|
|
+
|
|
|
+ g_free (priv->filename);
|
|
|
+ g_free (priv->template);
|
|
|
+
|
|
|
+ G_OBJECT_CLASS (ufo_edf_3d_writer_task_parent_class)->finalize (object);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_task_interface_init (UfoTaskIface *iface)
|
|
|
+{
|
|
|
+ iface->setup = ufo_edf_3d_writer_task_setup;
|
|
|
+ iface->get_structure = ufo_edf_3d_writer_task_get_structure;
|
|
|
+ iface->get_requisition = ufo_edf_3d_writer_task_get_requisition;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_cpu_task_interface_init (UfoCpuTaskIface *iface)
|
|
|
+{
|
|
|
+ iface->process = ufo_edf_3d_writer_task_process;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_class_init (UfoEdf3dWriterTaskClass *klass)
|
|
|
+{
|
|
|
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
+
|
|
|
+ gobject_class->set_property = ufo_edf_3d_writer_task_set_property;
|
|
|
+ gobject_class->get_property = ufo_edf_3d_writer_task_get_property;
|
|
|
+ gobject_class->finalize = ufo_edf_3d_writer_task_finalize;
|
|
|
+
|
|
|
+ properties[PROP_FILENAME] =
|
|
|
+ g_param_spec_string ("filename",
|
|
|
+ "Filename format string",
|
|
|
+ "Format string of the path and filename. If multiple files are written it must contain a '%i' specifier denoting the current count",
|
|
|
+ "./output-%05i.edf",
|
|
|
+ G_PARAM_READWRITE);
|
|
|
+
|
|
|
+ for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
|
|
|
+ g_object_class_install_property (gobject_class, i, properties[i]);
|
|
|
+
|
|
|
+ g_type_class_add_private (gobject_class, sizeof(UfoEdf3dWriterTaskPrivate));
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+ufo_edf_3d_writer_task_init(UfoEdf3dWriterTask *self)
|
|
|
+{
|
|
|
+ self->priv = UFO_EDF_3D_WRITER_TASK_GET_PRIVATE(self);
|
|
|
+ self->priv->filename = g_strdup ("./output-%05i.edf");
|
|
|
+ self->priv->template = NULL;
|
|
|
+ self->priv->counter = 0;
|
|
|
+}
|