[ismrmrd] 05/177: Starting to flesh out C interface.

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:01:55 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to annotated tag v1.1.0.beta.1
in repository ismrmrd.

commit d27929d26c8e376ebcd248dab53591e48db37590
Author: Souheil Inati <souheil.inati at nih.gov>
Date:   Sat Jul 19 22:41:07 2014 -0400

    Starting to flesh out C interface.
---
 ismrmrd.c                |  382 +++++++++++++
 ismrmrd.h                | 1419 +++++++++-------------------------------------
 ismrmrd_hdf5.h           |    8 +-
 ismrmrd_hdf5_datatypes.h |  345 +----------
 4 files changed, 667 insertions(+), 1487 deletions(-)

diff --git a/ismrmrd.c b/ismrmrd.c
new file mode 100644
index 0000000..e64b854
--- /dev/null
+++ b/ismrmrd.c
@@ -0,0 +1,382 @@
+#include <ismrmrd.h>
+
+#ifdef __cplusplus
+namespace ISMRMRD
+{
+extern "C" {
+#endif
+
+    /**********************/
+    /* Acquisition Header */
+    /**********************/
+    void InitAcquisitionHeader(AcquisitionHeader* hdr)
+    {
+	memset(hdr, 0, sizeof(AcquisitionHeader));
+	hdr->version = ISMRMRD_VERSION;
+	hdr->number_of_samples = 0;
+	hdr->available_channels = 1;
+	hdr->active_channels = 1;
+    }
+
+    /***************/
+    /* Acquisition */
+    /***************/
+    void InitAcquisition(Acquisition* acq) {
+	InitAcquisitionHeader(&(acq->head));
+	acq->traj = NULL;
+	acq->data = NULL;
+    }
+
+    void CopyAcquisition(Acquisition* acqdest, const Acquisition* acqsource) {
+	memcpy(&(acqdest->head), &(acqsource->head), sizeof(AcquisitionHeader));
+	MakeConsistentAcquisition(acqdest);
+	memcpy(&(acqdest->traj), &(acqsource->traj), acqdest->head.number_of_samples *  acqdest->head.trajectory_dimensions * sizeof(acqdest->traj));
+	memcpy(&(acqdest->data), &(acqsource->data), acqdest->head.number_of_samples *  acqdest->head.active_channels * sizeof(acqdest->data));
+    }
+
+    void FreeAcquisition(Acquisition* acq) {
+	free(acq->data);
+	free(acq->traj);
+	free(acq);
+    }
+
+    void MakeConsistentAcquisition(Acquisition* acq) {
+	if (acq->head.available_channels < acq->head.active_channels) {
+	    acq->head.available_channels = acq->head.active_channels;
+	}
+
+	int num_traj = acq->head.number_of_samples *  acq->head.trajectory_dimensions;
+	if (num_traj > 0) {
+	    acq->traj = (float *) realloc(acq->traj, num_traj * sizeof(acq->traj));
+	}
+
+	int num_data = acq->head.number_of_samples *  acq->head.active_channels;
+	if (num_data > 0) {
+	    acq->data = (complex_float_t *)realloc(acq->data, num_data * sizeof(acq->data));
+	}
+    }
+
+    /****************/
+    /* Image Header */
+    /****************/
+    void InitImageHeader(ImageHeader* hdr) {
+	memset(hdr, 0, sizeof(ImageHeader));
+	hdr->version = ISMRMRD_VERSION;
+	hdr->matrix_size[0] = 0;
+	hdr->matrix_size[1] = 1;
+	hdr->matrix_size[2] = 1;
+	hdr->channels  = 1;
+    }
+
+
+    /*********/
+    /* Image */
+    /*********/
+    void InitImage(Image* im) {
+	InitImageHeader(&(im->head));
+	im->attribute_string = NULL;
+	im->data = NULL;
+    }
+
+    void FreeImage(Image* im) {
+	free(im->data);
+	free(im->attribute_string);
+	free(im);
+    }
+
+    int SizeOfImageData(const Image* im) {
+	int data_size = 0;
+	int num_data =  im->head.matrix_size[0] * im->head.matrix_size[1] * im->head.matrix_size[2] * im->head.channels;
+	if (num_data > 0) {
+	    switch (im->head.data_type) {
+	    case DATA_UNSIGNED_SHORT:
+		data_size =num_data * sizeof(uint16_t);
+		break;
+	    case DATA_SHORT:
+		data_size = num_data * sizeof(int16_t);
+		break;
+	    case DATA_UNSIGNED_INT:
+		data_size = num_data * sizeof(uint32_t);
+		break;
+	    case DATA_INT:
+		data_size = num_data * sizeof(int32_t);
+		break;
+	    case DATA_FLOAT:
+		data_size = num_data * sizeof(float);
+		break;
+	    case DATA_DOUBLE:
+		data_size = num_data * sizeof(double);
+		break;
+	    case DATA_COMPLEX_FLOAT:
+		data_size = num_data * sizeof(complex_float_t);
+		break;
+	    case DATA_COMPLEX_DOUBLE:
+		data_size = num_data * sizeof(complex_double_t);
+		break;
+	    }
+	}
+	return data_size;
+    }
+
+    int SizeOfImageAttributeString(const Image* im) {
+	int attribute_string_size = 0;
+	if (im->head.attribute_string_len > 0) {
+	    attribute_string_size = im->head.attribute_string_len * sizeof(im->attribute_string);
+	}
+	return attribute_string_size;
+    }
+
+    void MakeConsistentImage(Image* im) {
+	int attr_size =  SizeOfImageAttributeString(im);
+	if (attr_size > 0) {
+	    im->attribute_string = (char *) realloc(im->attribute_string,  attr_size);
+	}
+	int data_size =  SizeOfImageData(im);
+	if (data_size > 0) {
+	    im->data = realloc(im->data, data_size);
+	}
+    }
+
+    void CopyImage(Image* imdest, const Image* imsource) {
+	memcpy(&(imdest->head), &(imsource->head), sizeof(ImageHeader));
+	MakeConsistentImage(imdest);
+	int attr_size =  SizeOfImageAttributeString(imdest);
+	if (attr_size > 0) {	
+	    memcpy(&(imdest->attribute_string), &(imsource->attribute_string), attr_size);
+	}
+	int data_size =  SizeOfImageData(imdest);
+	if (data_size > 0) {
+	    memcpy(&(imdest->data), &(imsource->data), data_size);
+	}
+    }
+
+    /***********/
+    /* NDArray */
+    /***********/
+    void InitNDArray(NDArray* arr) {
+	arr->version = ISMRMRD_VERSION;
+	arr->data_type = 0;  // no default data type
+	arr->ndim = 0;
+	for (int n=0; n<ISMRMRD_NDARRAY_MAXDIM; n++) {
+	    arr->dims[n] = 1;
+	}
+	arr->data = NULL;
+    }
+
+    void FreeNDArray(NDArray* arr) {
+	free(arr->data);
+	free(arr);
+    }
+
+    int SizeOfNDArrayData(const NDArray* arr) {
+	int data_size = 0;
+	int num_data =  1;
+	for (int n=0; n<ISMRMRD_NDARRAY_MAXDIM; n++) {
+	    num_data *= arr->dims[n];
+	}
+	if (num_data > 0) {
+	    switch (arr->data_type) {
+	    case DATA_UNSIGNED_SHORT:
+		data_size = num_data * sizeof(uint16_t);
+		break;
+	    case DATA_SHORT:
+		data_size = num_data * sizeof(int16_t);
+		break;
+	    case DATA_UNSIGNED_INT:
+		data_size = num_data * sizeof(uint32_t);
+		break;
+	    case DATA_INT:
+		data_size = num_data * sizeof(int32_t);
+		break;
+	    case DATA_FLOAT:
+		data_size = num_data * sizeof(float);
+		break;
+	    case DATA_DOUBLE:
+		data_size = num_data * sizeof(double);
+		break;
+	    case DATA_COMPLEX_FLOAT:
+		data_size= num_data * sizeof(complex_float_t);
+		break;
+	    case DATA_COMPLEX_DOUBLE:
+		data_size = num_data * sizeof(complex_double_t);
+		break;
+	    }
+	}
+	return data_size;
+    }
+
+    void MakeConsistentNDArray(NDArray* arr) {
+	int data_size =  SizeOfNDArrayData(arr);
+	if (data_size > 0) {
+	    arr->data = realloc(arr->data, data_size);
+	}
+    }
+
+    void CopyNDArray(NDArray* arrdest, const NDArray* arrsource) {
+	arrdest->version = arrsource->version;
+	arrdest->data_type = arrsource->data_type;
+	arrdest->ndim = arrsource->ndim;
+	for (int n=0; n<ISMRMRD_NDARRAY_MAXDIM; n++) {
+	    arrdest->dims[n] = arrsource->dims[n];
+	}
+	MakeConsistentNDArray(arrdest);
+	int data_size =  SizeOfNDArrayData(arrdest);
+	if (data_size > 0) {
+	    memcpy(&(arrdest->data), &(arrsource->data), SizeOfNDArrayData(arrdest));
+	}
+    }
+
+
+    /******************************/
+    /* Flag convenience functions */
+    /******************************/
+    bool flags_is_set(const uint64_t flags, const uint64_t val) {
+	uint64_t bitmask = 1;
+	bitmask = (bitmask << (val-1));
+	return ((flags & bitmask) > 0);
+    }
+  
+    void flags_set(uint64_t* flags, const uint64_t val) {
+	uint64_t bitmask = 1;
+	bitmask = (bitmask << (val-1));
+	*flags |= bitmask;
+    }
+
+    void flags_clear(uint64_t* flags, const uint64_t val) {
+	uint64_t bitmask = 1;
+	bitmask = (bitmask << (val-1));
+	if (flags_is_set(*flags, val)) {
+	    *flags &= ~bitmask;
+	};
+    }
+
+    void flags_clear_all(uint64_t* flags) {
+	*flags = 0;
+    }
+
+    /******************************/
+    /* Quaternions and Rotations  */
+    /******************************/
+
+    /**
+     * Calculates the determinant of the matrix and return the sign
+     */
+    int sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3])
+    {
+	float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
+	float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
+	float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
+
+	/* Determinant should be 1 or -1 */
+	float deti = (r11 * r22 * r33) + (r12 * r23 * r31) + (r21 * r32 * r13) -
+	    (r13 * r22 * r31) - (r12 * r21 * r33) - (r11 * r23 * r32);
+
+	if (deti < 0) {
+	    return -1;
+	} else {
+	    return 1;
+	}
+    }
+
+    /**
+     * Creates a normalized quaternion from a 3x3 rotation matrix
+     */
+    void directions_to_quaternion(float read_dir[3], float phase_dir[3],
+				  float slice_dir[3], float quat[4])
+    {
+	float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
+	float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
+	float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
+
+	double a = 1, b = 0, c = 0, d = 0, s = 0;
+	double trace = 0;
+	double xd, yd, zd;
+
+	/* verify the sign of the rotation*/
+	if (sign_of_directions(read_dir, phase_dir, slice_dir) < 0) {
+	    /* flip 3rd column */
+	    r13 = -r13;
+	    r23 = -r23;
+	    r33 = -r33;
+	}
+
+	/* Compute quaternion parameters */
+	/* http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q55 */
+	trace = 1.0l + r11 + r22 + r33;
+	if (trace > 0.00001l) {                /* simplest case */
+	    s = sqrt(trace) * 2;
+	    a = (r32 - r23) / s;
+	    b = (r13 - r31) / s;
+	    c = (r21 - r12) / s;
+	    d = 0.25l * s;
+	} else {
+	    /* trickier case...
+	     * determine which major diagonal element has
+	     * the greatest value... */
+	    xd = 1.0 + r11 - (r22 + r33);  /* 4**b**b */
+	    yd = 1.0 + r22 - (r11 + r33);  /* 4**c**c */
+	    zd = 1.0 + r33 - (r11 + r22);  /* 4**d**d */
+	    /* if r11 is the greatest */
+	    if (xd > 1.0) {
+		s = 2.0 * sqrt(xd);
+		a = 0.25l * s;
+		b = (r21 + r12) / s;
+		c = (r31 + r13) / s;
+		d = (r32 - r23) / s;
+	    }
+	    /* else if r22 is the greatest */
+	    else if (yd > 1.0) {
+		s = 2.0 * sqrt(yd);
+		a = (r21 + r12) / s;
+		b = 0.25l * s;
+		c = (r32 + r23) / s;
+		d = (r13 - r31) / s;
+	    }
+	    /* else, r33 must be the greatest */
+	    else {
+		s = 2.0 * sqrt(zd);
+		a = (r13 + r31) / s;
+		b = (r23 + r32) / s;
+		c = 0.25l * s;
+		d = (r21 - r12) / s;
+	    }
+
+	    if (a < 0.0l) {
+		b = -b;
+		c = -c;
+		d = -d;
+		a = -a;
+	    }
+	}
+
+	quat[0] = (float)a; quat[1] = (float)b; quat[2] = (float)c; quat[3] = (float)d;
+    }
+
+    /**
+     * Converts a quaternion of the form | a b c d | to a
+     * 3x3 rotation matrix
+     *
+     * http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q54
+     */
+    void quaternion_to_directions(float quat[4], float read_dir[3],
+				  float phase_dir[3], float slice_dir[3])
+    {
+	float a = quat[0], b = quat[1], c = quat[2], d = quat[3];
+
+	read_dir[0]  = 1.0f - 2.0f * ( b*b + c*c );
+	phase_dir[0] = 2.0f * ( a*b - c*d );
+	slice_dir[0] = 2.0f * ( a*c + b*d );
+
+	read_dir[1]  = 2.0f * ( a*b + c*d );
+	phase_dir[1] = 1.0f - 2.0f * ( a*a + c*c );
+	slice_dir[1] = 2.0f * ( b*c - a*d );
+
+	read_dir[2]  = 2.0f * ( a*c - b*d );
+	phase_dir[2] = 2.0f * ( b*c + a*d );
+	slice_dir[2] = 1.0f - 2.0f * ( a*a + b*b );
+    }
+
+#ifdef __cplusplus
+} //End of extern C
+} //End of namespace
+#endif
diff --git a/ismrmrd.h b/ismrmrd.h
index 33defe4..d9db4cb 100644
--- a/ismrmrd.h
+++ b/ismrmrd.h
@@ -13,1198 +13,319 @@
 #ifndef ISMRMRD_H
 #define ISMRMRD_H
 
-/* Cross platform section for defining integer types */
-#ifndef ISMRMRD_HAS_BASIC_TYPES
+/* Language and Cross platform section for defining types */
+#ifdef __cplusplus
+
 #ifdef _MSC_VER
+// MS C++ Compiler
 typedef __int16 int16_t;
 typedef unsigned __int16 uint16_t;
 typedef __int32 int32_t;
 typedef unsigned __int32 uint32_t;
 typedef __int64 int64_t;
 typedef unsigned __int64 uint64_t;
+
 #else
-#include <stdint.h>
-#include <math.h>
-#endif
+// non MS C++ compiler
+#include <cstdint>
 #endif
 
-#ifdef __cplusplus
-#include <stdio.h>
-#include <string.h>
-#include <exception>
-#include <iostream>
-#include <vector>
-#include <valarray>
+#include <cstdlib>
+#include <cstring>
 #include <complex>
-#include <assert.h>
-#endif
+#include <cmath>
+typedef std::complex<float> complex_float_t;
+typedef std::complex<double> complex_double_t;
 
-#pragma pack(push, 2) //Use 2 byte alignment
+#else
+// C99 compiler
+#include <stdint.h>
+#include <complex.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+typedef float complex complex_float_t;
+typedef double complex complex_double_t;
 
-#define ISMRMRD_VERSION           1
-#define ISMRMRD_POSITION_LENGTH   3
-#define ISMRMRD_DIRECTION_LENGTH  3
-#define ISMRMRD_USER_INTS         8
-#define ISMRMRD_USER_FLOATS       8
-#define ISMRMRD_PHYS_STAMPS       8  //TODO: This should be changed to 3 (Major impact)
-#define ISMRMRD_CHANNEL_MASKS     16
+#endif  // __cplusplus
 
-#ifdef __cplusplus
-namespace ISMRMRD
-{
+#pragma pack(push, 2)  // Use 2 byte alignment
+
+#define ISMRMRD_VERSION 1
+#define ISMRMRD_POSITION_LENGTH 3
+#define ISMRMRD_DIRECTION_LENGTH 3
+#define ISMRMRD_USER_INTS 8
+#define ISMRMRD_USER_FLOATS 8
+#define ISMRMRD_PHYS_STAMPS 3
+#define ISMRMRD_CHANNEL_MASKS 16
+#define ISMRMRD_NDARRAY_MAXDIM 7
 
-class FlagBit
-{
-public:
- FlagBit(unsigned short b)
-   : bitmask_(0)
-    {
-      if (b > 0) {
-    bitmask_ = 1;
-    bitmask_ = (bitmask_ << (b-1));
-      }
-    }
-  
-  bool isSet(const uint64_t& m) const {
-    return ((m & bitmask_)>0);
-  }
-  
-  uint64_t bitmask_;
-  
+#ifdef __cplusplus
+namespace ISMRMRD {
+#endif  //__cplusplus
+
+/**************/
+/* Data Types */
+/**************/
+enum DataTypes {
+  DATA_UNSIGNED_SHORT = 1,  // corresponds to uint16_t
+  DATA_SHORT,               // corresponds to int16_t
+  DATA_UNSIGNED_INT,        // corresponds to uint32_t
+  DATA_INT,                 // corresponds to int32_t
+  DATA_FLOAT,               // corresponds to float
+  DATA_DOUBLE,              // corresponds to double
+  DATA_COMPLEX_FLOAT,       // corresponds to complex float
+  DATA_COMPLEX_DOUBLE,      // corresponds to complex double
 };
-#endif //__cplusplus
+
+/****************/
+/* Acquisitions */
+/****************/
 
 /** ACQUISITION FLAGS */
 enum AcquisitionFlags {
-    /* Looping indicators */
-    ACQ_FIRST_IN_ENCODE_STEP1                   = 1,
-    ACQ_LAST_IN_ENCODE_STEP1                    = 2,
-    ACQ_FIRST_IN_ENCODE_STEP2                   = 3,
-    ACQ_LAST_IN_ENCODE_STEP2                    = 4,
-    ACQ_FIRST_IN_AVERAGE                        = 5,
-    ACQ_LAST_IN_AVERAGE                         = 6,
-    ACQ_FIRST_IN_SLICE                          = 7,
-    ACQ_LAST_IN_SLICE                           = 8,
-    ACQ_FIRST_IN_CONTRAST                       = 9,
-    ACQ_LAST_IN_CONTRAST                        = 10,
-    ACQ_FIRST_IN_PHASE                          = 11,
-    ACQ_LAST_IN_PHASE                           = 12,
-    ACQ_FIRST_IN_REPETITION                     = 13,
-    ACQ_LAST_IN_REPETITION                      = 14,
-    ACQ_FIRST_IN_SET                            = 15,
-    ACQ_LAST_IN_SET                             = 16,
-    ACQ_FIRST_IN_SEGMENT                        = 17,
-    ACQ_LAST_IN_SEGMENT                         = 18,
-    ACQ_IS_NOISE_MEASUREMENT                    = 19,
-    ACQ_IS_PARALLEL_CALIBRATION                 = 20,
-    ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING     = 21,
-    ACQ_IS_REVERSE                              = 22,
-    ACQ_IS_NAVIGATION_DATA                      = 23,
-    ACQ_IS_PHASECORR_DATA                       = 24,
-    ACQ_LAST_IN_MEASUREMENT                     = 25,
-    ACQ_IS_HPFEEDBACK_DATA                      = 26,
-    ACQ_IS_DUMMYSCAN_DATA                       = 27,
-    ACQ_IS_RTFEEDBACK_DATA                      = 28,
-    ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA       = 29,
-
-    ACQ_USER1                                   = 57,
-    ACQ_USER2                                   = 58,
-    ACQ_USER3                                   = 59,
-    ACQ_USER4                                   = 60,
-    ACQ_USER5                                   = 61,
-    ACQ_USER6                                   = 62,
-    ACQ_USER7                                   = 63,
-    ACQ_USER8                                   = 64
+  /* Looping indicators */
+  ACQ_FIRST_IN_ENCODE_STEP1 = 1,
+  ACQ_LAST_IN_ENCODE_STEP1 = 2,
+  ACQ_FIRST_IN_ENCODE_STEP2 = 3,
+  ACQ_LAST_IN_ENCODE_STEP2 = 4,
+  ACQ_FIRST_IN_AVERAGE = 5,
+  ACQ_LAST_IN_AVERAGE = 6,
+  ACQ_FIRST_IN_SLICE = 7,
+  ACQ_LAST_IN_SLICE = 8,
+  ACQ_FIRST_IN_CONTRAST = 9,
+  ACQ_LAST_IN_CONTRAST = 10,
+  ACQ_FIRST_IN_PHASE = 11,
+  ACQ_LAST_IN_PHASE = 12,
+  ACQ_FIRST_IN_REPETITION = 13,
+  ACQ_LAST_IN_REPETITION = 14,
+  ACQ_FIRST_IN_SET = 15,
+  ACQ_LAST_IN_SET = 16,
+  ACQ_FIRST_IN_SEGMENT = 17,
+  ACQ_LAST_IN_SEGMENT = 18,
+  ACQ_IS_NOISE_MEASUREMENT = 19,
+  ACQ_IS_PARALLEL_CALIBRATION = 20,
+  ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING = 21,
+  ACQ_IS_REVERSE = 22,
+  ACQ_IS_NAVIGATION_DATA = 23,
+  ACQ_IS_PHASECORR_DATA = 24,
+  ACQ_LAST_IN_MEASUREMENT = 25,
+  ACQ_IS_HPFEEDBACK_DATA = 26,
+  ACQ_IS_DUMMYSCAN_DATA = 27,
+  ACQ_IS_RTFEEDBACK_DATA = 28,
+  ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA = 29,
+  ACQ_USER1 = 57,
+  ACQ_USER2 = 58,
+  ACQ_USER3 = 59,
+  ACQ_USER4 = 60,
+  ACQ_USER5 = 61,
+  ACQ_USER6 = 62,
+  ACQ_USER7 = 63,
+  ACQ_USER8 = 64
 };
 
 /**
-     Struct used for keeping track of typical loop counters in MR experiment.
-
- */
+   Struct used for keeping track of typical loop counters in MR experiment.
+*/
 typedef struct EncodingCounters {
-    uint16_t kspace_encode_step_1;     /**< e.g. phase encoding line number */
-    uint16_t kspace_encode_step_2;     /**< e.g. partition encodning number */
-    uint16_t average;                  /**< e.g. signal average number */
-    uint16_t slice;                    /**< e.g. imaging slice number */
-    uint16_t contrast;                 /**< e.g. echo number in multi-echo */
-    uint16_t phase;                    /**< e.g. cardiac phase number */
-    uint16_t repetition;               /**< e.g. dynamic number for dynamic scanning */
-    uint16_t set;                      /**< e.g. flow encodning set */
-    uint16_t segment;                  /**< e.g. segment number for segmented acquisition */
-    uint16_t user[ISMRMRD_USER_INTS];  /**< Free user parameters */
+  uint16_t kspace_encode_step_1; /**< e.g. phase encoding line number */
+  uint16_t kspace_encode_step_2; /**< e.g. partition encodning number */
+  uint16_t average;              /**< e.g. signal average number */
+  uint16_t slice;                /**< e.g. imaging slice number */
+  uint16_t contrast;             /**< e.g. echo number in multi-echo */
+  uint16_t phase;                /**< e.g. cardiac phase number */
+  uint16_t repetition; /**< e.g. dynamic number for dynamic scanning */
+  uint16_t set;        /**< e.g. flow encodning set */
+  uint16_t segment;    /**< e.g. segment number for segmented acquisition */
+  uint16_t user[ISMRMRD_USER_INTS]; /**< Free user parameters */
 } EncodingCounters;
 
 /**
-     Header for each MR acquisition.
- */
-typedef struct AcquisitionHeader
-{
-    uint16_t           version;                                          /**< First unsigned int indicates the version */
-    uint64_t           flags;                                            /**< bit field with flags */
-    uint32_t           measurement_uid;                                  /**< Unique ID for the measurement */
-    uint32_t           scan_counter;                                     /**< Current acquisition number in the measurement */
-    uint32_t           acquisition_time_stamp;                           /**< Acquisition clock */
-    uint32_t           physiology_time_stamp[ISMRMRD_PHYS_STAMPS];       /**< Physiology time stamps, e.g. ecg, breating, etc. */
-    uint16_t           number_of_samples;                                /**< Number of samples acquired */
-    uint16_t           available_channels;                               /**< Available coils */
-    uint16_t           active_channels;                                  /**< Active coils on current acquisiton */
-    uint64_t           channel_mask[ISMRMRD_CHANNEL_MASKS];              /**< Mask to indicate which channels are active. Support for 1024 channels */
-    uint16_t           discard_pre;                                      /**< Samples to be discarded at the beginning of acquisition */
-    uint16_t           discard_post;                                     /**< Samples to be discarded at the end of acquisition */
-    uint16_t           center_sample;                                    /**< Sample at the center of k-space */
-    uint16_t           encoding_space_ref;                               /**< Reference to an encoding space, typically only one per acquisition */
-    uint16_t           trajectory_dimensions;                            /**< Indicates the dimensionality of the trajectory vector (0 means no trajectory) */
-    float              sample_time_us;                                   /**< Time between samples in micro seconds, sampling BW */
-    float              position[ISMRMRD_POSITION_LENGTH];                /**< Three-dimensional spatial offsets from isocenter */
-    float              read_dir[ISMRMRD_DIRECTION_LENGTH];               /**< Directional cosines of the readout/frequency encoding */
-    float              phase_dir[ISMRMRD_DIRECTION_LENGTH];              /**< Directional cosines of the phase */
-    float              slice_dir[ISMRMRD_DIRECTION_LENGTH];              /**< Directional cosines of the slice direction */
-    float              patient_table_position[ISMRMRD_POSITION_LENGTH];  /**< Patient table off-center */
-    EncodingCounters   idx;                                              /**< Encoding loop counters, see above */
-    int32_t            user_int[ISMRMRD_USER_INTS];                      /**< Free user parameters */
-    float              user_float[ISMRMRD_USER_FLOATS];                  /**< Free user parameters */
+   Header for each MR acquisition.
+*/
+typedef struct AcquisitionHeader {
+  uint16_t version;         /**< First unsigned int indicates the version */
+  uint64_t flags;           /**< bit field with flags */
+  uint32_t measurement_uid; /**< Unique ID for the measurement */
+  uint32_t scan_counter; /**< Current acquisition number in the measurement */
+  uint32_t acquisition_time_stamp;                     /**< Acquisition clock */
+  uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS]; /**< Physiology time
+                                                          stamps, e.g. ecg,
+                                                          breating, etc. */
+  uint16_t number_of_samples;  /**< Number of samples acquired */
+  uint16_t available_channels; /**< Available coils */
+  uint16_t active_channels;    /**< Active coils on current acquisiton */
+  uint64_t
+      channel_mask
+          [ISMRMRD_CHANNEL_MASKS]; /**< Mask to indicate which channels are
+                                      active. Support for 1024 channels */
+  uint16_t discard_pre; /**< Samples to be discarded at the beginning of
+                           acquisition */
+  uint16_t
+      discard_post; /**< Samples to be discarded at the end of acquisition */
+  uint16_t center_sample;      /**< Sample at the center of k-space */
+  uint16_t encoding_space_ref; /**< Reference to an encoding space, typically
+                                  only one per acquisition */
+  uint16_t trajectory_dimensions; /**< Indicates the dimensionality of the
+                                     trajectory vector (0 means no trajectory)
+                                     */
+  float
+      sample_time_us; /**< Time between samples in micro seconds, sampling BW */
+  float position[ISMRMRD_POSITION_LENGTH]; /**< Three-dimensional spatial
+                                              offsets from isocenter */
+  float read_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+                                               readout/frequency encoding */
+  float phase_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+                                                phase */
+  float slice_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+                                                slice direction */
+  float patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table
+                                                            off-center */
+  EncodingCounters idx;                /**< Encoding loop counters, see above */
+  int32_t user_int[ISMRMRD_USER_INTS]; /**< Free user parameters */
+  float user_float[ISMRMRD_USER_FLOATS]; /**< Free user parameters */
 } AcquisitionHeader;
 
-enum ImageDataType
-{
-    DATA_FLOAT = 1,
-    DATA_DOUBLE,
-    DATA_COMPLEX_FLOAT,
-    DATA_COMPLEX_DOUBLE,
-    DATA_UNSIGNED_SHORT
-};
+/* Initialize an Acquisition Header */
+void initAcquisitionHeader(AcquisitionHeader* hdr);
 
-enum ImageType
-{
-    TYPE_MAGNITUDE = 1,
-    TYPE_PHASE,
-    TYPE_REAL,
-    TYPE_IMAG,
-    TYPE_COMPLEX
+/**
+   Individual MR acquisition.
+*/
+typedef struct Acquisition {
+  AcquisitionHeader head; /**< Header, see above */
+  float* traj;
+  complex_float_t* data;
+} Acquisition;
+
+void initAcquisition(Acquisition* acq);
+void copyAcquisition(Acquisition* acqdest, const Acquisition* acqsource);
+void freeAcquisition(Acquisition* acq);
+void makeConsistentAcquisition(Acquisition* acq);
+
+/**********/
+/* Images */
+/**********/
+
+enum ImageType {
+  TYPE_MAGNITUDE = 1,
+  TYPE_PHASE,
+  TYPE_REAL,
+  TYPE_IMAG,
+  TYPE_COMPLEX
 };
 
 /** IMAGE FLAGS */
 enum ImageFlags {
-    IMAGE_IS_NAVIGATION_DATA                      = 23,
-
-    IMAGE_USER1                                   = 57,
-    IMAGE_USER2                                   = 58,
-    IMAGE_USER3                                   = 59,
-    IMAGE_USER4                                   = 60,
-    IMAGE_USER5                                   = 61,
-    IMAGE_USER6                                   = 62,
-    IMAGE_USER7                                   = 63,
-    IMAGE_USER8                                   = 64
+  IMAGE_IS_NAVIGATION_DATA = 23,
+  IMAGE_USER1 = 57,
+  IMAGE_USER2 = 58,
+  IMAGE_USER3 = 59,
+  IMAGE_USER4 = 60,
+  IMAGE_USER5 = 61,
+  IMAGE_USER6 = 62,
+  IMAGE_USER7 = 63,
+  IMAGE_USER8 = 64
 };
 
 /**
- *  Definition of ISMRM Raw Data Image structure
+ *  Header for each Image
  */
-typedef struct ImageHeader
-{
-    uint16_t            version;                                         /**< First unsigned int indicates the version */
-    uint64_t            flags;                                           /**< bit field with flags */
-    uint32_t            measurement_uid;                                 /**< Unique ID for the measurement  */
-    uint16_t            matrix_size[3];                                  /**< Pixels in the 3 spatial dimensions */
-    float               field_of_view[3];                                /**< Size (in mm) of the 3 spatial dimensions */
-    uint16_t            channels;                                        /**< Number of receive channels */
-    float               position[ISMRMRD_POSITION_LENGTH];               /**< Three-dimensional spatial offsets from isocenter */
-    float               read_dir[ISMRMRD_DIRECTION_LENGTH];              /**< Directional cosines of the readout/frequency encoding */
-    float               phase_dir[ISMRMRD_DIRECTION_LENGTH];             /**< Directional cosines of the phase */
-    float               slice_dir[ISMRMRD_DIRECTION_LENGTH];             /**< Directional cosines of the slice direction */
-    float               patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table off-center */
-    uint16_t            average;                                         /**< e.g. signal average number */
-    uint16_t            slice;                                           /**< e.g. imaging slice number */
-    uint16_t            contrast;                                        /**< e.g. echo number in multi-echo */
-    uint16_t            phase;                                           /**< e.g. cardiac phase number */
-    uint16_t            repetition;                                      /**< e.g. dynamic number for dynamic scanning */
-    uint16_t            set;                                             /**< e.g. flow encodning set */
-    uint32_t            acquisition_time_stamp;                          /**< Acquisition clock */
-    uint32_t            physiology_time_stamp[ISMRMRD_PHYS_STAMPS];      /**< Physiology time stamps, e.g. ecg, breating, etc. */
-    uint16_t            image_data_type;                                 /**< e.g. unsigned short, float, complex float, etc. */
-    uint16_t            image_type;                                      /**< e.g. magnitude, phase, complex, real, imag, etc. */
-    uint16_t            image_index;                                     /**< e.g. image number in series of images  */
-    uint16_t            image_series_index;                              /**< e.g. series number */
-    int32_t             user_int[ISMRMRD_USER_INTS];                     /**< Free user parameters */
-    float               user_float[ISMRMRD_USER_FLOATS];                 /**< Free user parameters */
+typedef struct ImageHeader {
+  uint16_t version;   /**< First unsigned int indicates the version */
+  uint16_t data_type; /**< e.g. unsigned short, float, complex float, etc. */
+  uint64_t flags;     /**< bit field with flags */
+  uint32_t measurement_uid; /**< Unique ID for the measurement  */
+  uint16_t matrix_size[3];  /**< Pixels in the 3 spatial dimensions */
+  float field_of_view[3];   /**< Size (in mm) of the 3 spatial dimensions */
+  uint16_t channels;        /**< Number of receive channels */
+  float position[ISMRMRD_POSITION_LENGTH]; /**< Three-dimensional spatial
+                                              offsets from isocenter */
+  float read_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+                                               readout/frequency encoding */
+  float phase_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+                                                phase */
+  float slice_dir[ISMRMRD_DIRECTION_LENGTH]; /**< Directional cosines of the
+                                                slice direction */
+  float patient_table_position[ISMRMRD_POSITION_LENGTH]; /**< Patient table
+                                                            off-center */
+  uint16_t average;    /**< e.g. signal average number */
+  uint16_t slice;      /**< e.g. imaging slice number */
+  uint16_t contrast;   /**< e.g. echo number in multi-echo */
+  uint16_t phase;      /**< e.g. cardiac phase number */
+  uint16_t repetition; /**< e.g. dynamic number for dynamic scanning */
+  uint16_t set;        /**< e.g. flow encodning set */
+  uint32_t acquisition_time_stamp;                     /**< Acquisition clock */
+  uint32_t physiology_time_stamp[ISMRMRD_PHYS_STAMPS]; /**< Physiology time
+                                                          stamps, e.g. ecg,
+                                                          breating, etc. */
+  uint16_t image_type;  /**< e.g. magnitude, phase, complex, real, imag, etc. */
+  uint16_t image_index; /**< e.g. image number in series of images  */
+  uint16_t image_series_index;           /**< e.g. series number */
+  int32_t user_int[ISMRMRD_USER_INTS];   /**< Free user parameters */
+  float user_float[ISMRMRD_USER_FLOATS]; /**< Free user parameters */
+  uint32_t attribute_string_len;         /**< Length of attributes string */
 } ImageHeader;
 
-#ifdef __cplusplus
-/**
- *  Container for generic array. This structure is used through the HDF5 file interaction.
- */
-template <typename T> class NDArrayContainer {
-
-public:
-    NDArrayContainer() {}
-
-    /**
-     * @brief Construct with dimensions and data
-     */
-    NDArrayContainer(const std::vector<unsigned int>& dimensions) {
-        dimensions_ = dimensions;
-        data_.resize(elements());
-    }
-
-    /**
-     * @brief Construct with dimensions and data
-     */
-    NDArrayContainer(const std::vector<unsigned int>& dimensions, const T* d) {
-        dimensions_ = dimensions;
-        data_.resize(elements());
-        memcpy(&data_[0],d,sizeof(T)*elements());
-    }
-
-    /**
-     * @brief Construct with dimensions and preset value
-     */
-    NDArrayContainer(const std::vector<unsigned int>& dimensions, const std::valarray<T>& t) {
-        dimensions_ = dimensions;
-        data_.resize(elements());
-        data_ = t;
-    }
-
-    virtual ~NDArrayContainer() {}
-
-    std::vector<unsigned int> dimensions_; /**< Array with dimensions of the array. First dimension is fastest moving in the array */
-    std::valarray<T> data_;               /**< The data itself. A vector is used here for easy memory management                  */
-
-    size_t elements() const {
-        if (dimensions_.size() == 0) {
-            return 0;
-        }
-        size_t elements = 1;
-        std::vector<unsigned int>::const_iterator it = dimensions_.begin();
-        while (it != dimensions_.end()) {
-            elements *= *(it++);
-        }
-        return elements;
-    }
-
-    T& operator[] (const size_t& p) {
-        return data_[p];
-    }
-
-    T operator[] (const size_t& p) const {
-        return data_[p];
-    }
-
-    void resize (const size_t& s) {
-        data_.resize(s);
-    }
-
-    void resize (const size_t& s, const T& t) {
-        data_.resize(s,t);
-    }
-
-    bool is_consistent() const {
-        return (elements() == data_.size());
-    }
-
-    size_t ndims() const {
-        size_t i = 1, n_dimensions = 1;
-        for (; i < dimensions_.size(); i++)
-            n_dimensions += (size_t) (dimensions_[i] > 1);
-        return n_dimensions;
-    }
-
-};
+void initImageHeader(ImageHeader* hdr);
 
 /**
- *   Container for an image (header and data)
+ *  An individual Image
  */
-template <typename T>
-class Image {
-
-public:
-    Image(unsigned int matrix_size_x = 0,
-          unsigned int matrix_size_y = 1,
-          unsigned int matrix_size_z = 1,
-          unsigned int channels      = 1)
-    {
-        memset(&head_,0,sizeof(ImageHeader));
-        head_.version = ISMRMRD_VERSION;
-        head_.matrix_size[0] = matrix_size_x;
-        head_.matrix_size[1] = matrix_size_y;
-        head_.matrix_size[2] = matrix_size_z;
-        head_.channels       = channels;
-        setSpecificDataType();
-        makeConsistent();
-    }
-
-
-    Image(const Image& a) {   // copy constructor
-        if (this != &a) {
-            head_ = a.head_;
-            this->data_ = a.data_;
-            makeConsistent();
-        }
-    }
-
-    Image& operator=(const Image& a) {
-        if (this != &a) {
-            head_ = a.head_;
-            this->data_ = a.data_;
-            makeConsistent();
-        }
-        return *this;
-    }
-
-    ~Image() {}
-
-    bool isFlagSet(FlagBit& f) const {
-        return f.isSet(head_.flags);
-    }
-
-    void setFlag(FlagBit& f) {
-        head_.flags |= f.bitmask_;
-    }
-
-    size_t getNumberOfElements() const {
-        return head_.matrix_size[0]*
-            head_.matrix_size[1]*
-            head_.matrix_size[2]*
-            head_.channels;
-    }
-
-
-    uint32_t getAcquisitionTimeStamp() const {
-        return head_.acquisition_time_stamp;
-    }
-
-    void setAcquisitionTimeStamp(uint32_t acquisitionTimeStamp) {
-        head_.acquisition_time_stamp = acquisitionTimeStamp;
-    }
-
-    uint16_t getAverage() const {
-        return head_.average;
-    }
-
-    void setAverage(uint16_t average) {
-        this->head_.average = average;
-    }
-
-    uint16_t getChannels() const {
-        return head_.channels;
-    }
-
-    void setChannels(uint16_t channels) {
-        this->head_.channels = channels;
-    }
-
-    uint16_t getContrast() const {
-        return head_.contrast;
-    }
-
-    void setContrast(uint16_t contrast) {
-        this->head_.contrast = contrast;
-    }
-
-    float getFieldOfViewX() const {
-        return head_.field_of_view[0];
-    }
-
-    void setFieldOfViewX(float f) {
-        head_.field_of_view[0] = f;
-    }
-
-    float getFieldOfViewY() const {
-        return head_.field_of_view[1];
-    }
-
-    void setFieldOfViewY(float f) {
-        head_.field_of_view[1] = f;
-    }
-
-    float getFieldOfViewZ() const {
-        return head_.field_of_view[2];
-    }
-
-    void setFieldOfViewZ(float f) {
-        head_.field_of_view[2] = f;
-    }
-
-    uint64_t getFlags() const {
-        return head_.flags;
-    }
-
-    void setFlags(uint64_t flags) {
-        this->head_.flags = flags;
-    }
-
-    uint16_t getImageDataType() const {
-        return head_.image_data_type;
-    }
-
-    void setImageDataType(uint16_t imageDataType) {
-        head_.image_data_type = imageDataType;
-    }
-
-    uint16_t getImageIndex() const {
-        return head_.image_index;
-    }
-
-    void setImageIndex(uint16_t imageIndex) {
-        head_.image_index = imageIndex;
-    }
-
-    uint16_t getImageSeriesIndex() const {
-        return head_.image_series_index;
-    }
-
-    void setImageSeriesIndex(uint16_t imageSeriesIndex) {
-        head_.image_series_index = imageSeriesIndex;
-    }
-
-    uint16_t getImageType() const {
-        return head_.image_type;
-    }
-
-    void setImageType(uint16_t imageType) {
-        head_.image_type = imageType;
-    }
-
-    uint16_t getMatrixSizeX() const {
-        return head_.matrix_size[0];
-    }
-
-    void setMatrixSizeX(uint16_t s) {
-        head_.matrix_size[0] = s;
-        makeConsistent();
-    }
-
-    uint16_t getMatrixSizeY() const {
-        return head_.matrix_size[1];
-    }
-
-    void setMatrixSizeY(uint16_t s) {
-        head_.matrix_size[1] = s;
-        makeConsistent();
-    }
-
-    uint16_t getMatrixSizeZ() const {
-        return head_.matrix_size[2];
-    }
-
-    void setMatrixSizeZ(uint16_t s) {
-        head_.matrix_size[2] = s;
-        makeConsistent();
-    }
-
-
-    uint32_t getMeasurementUid() const {
-        return head_.measurement_uid;
-    }
-
-    void setMeasurementUid(uint32_t measurementUid) {
-        head_.measurement_uid = measurementUid;
-    }
-
-    const float getPatientTablePosition(unsigned int axis) const {
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            return head_.patient_table_position[axis];
-        }
-        return 0;
-    }
-
-    void setPatientTablePosition(unsigned int axis, float value) {
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            head_.patient_table_position[axis] = value;
-        }
-    }
-
-    const uint32_t getPhysiologyTimeStamp(unsigned int stamp_id) const {
-        if (stamp_id < ISMRMRD_PHYS_STAMPS) {
-            return head_.physiology_time_stamp[stamp_id];
-        }
-        return 0;
-    }
-
-    void setPhysiologyTimeStamp(unsigned int stamp_id, uint32_t value){
-        if (stamp_id < ISMRMRD_PHYS_STAMPS) {
-            head_.physiology_time_stamp[stamp_id] = value;
-        }
-    }
-
-    const float getPosition(unsigned int axis) const {
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            return head_.position[axis];
-        }
-        return 0;
-    }
-
-    void setPosition(unsigned int axis, float value){
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            head_.position[axis] = value;
-        }
-    }
-
-        const float getReadDirection(unsigned int index) const {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        return head_.read_dir[index];
-                }
-                return 0;
-        }
-
-        void setReadDirection(unsigned int index, float value) {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        head_.read_dir[index] = value;
-                }
-        }
-
-        const float getPhaseDirection(unsigned int index) const {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        return head_.phase_dir[index];
-                }
-                return 0;
-        }
-
-        void setPhaseDirection(unsigned int index, float value) {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        head_.phase_dir[index] = value;
-                }
-        }
-
-        const float getSliceDirection(unsigned int index) const {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        return head_.slice_dir[index];
-                }
-                return 0;
-        }
-
-        void setSliceDirection(unsigned int index, float value) {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        head_.slice_dir[index] = value;
-                }
-        }
-
-    uint16_t getPhase() const {
-        return head_.phase;
-    }
-
-    void setPhase(uint16_t phase) {
-        this->head_.phase = phase;
-    }
-
-
-    uint16_t getRepetition() const {
-        return head_.repetition;
-    }
-
-    void setRepetition(uint16_t repetition) {
-        this->head_.repetition = repetition;
-    }
-
-    uint16_t getSet() const {
-        return head_.set;
-    }
-
-    void setSet(uint16_t set) {
-        this->head_.set = set;
-    }
-
-    uint16_t getSlice() const {
-        return head_.slice;
-    }
-
-    void setSlice(uint16_t slice) {
-        this->head_.slice = slice;
-    }
-
-    const float getUserFloat(unsigned int index) const {
-        if (index < ISMRMRD_USER_FLOATS) {
-            return head_.user_float[index];
-        }
-        return 0.0f;
-    }
-
-    void setUserFloat(unsigned int index, float value) {
-        if (index < ISMRMRD_USER_FLOATS) {
-            head_.user_float[index] = value;
-        }
-    }
-
-    const int32_t getUserInt(unsigned int index) const {
-        if (index < ISMRMRD_USER_INTS) {
-            return head_.user_int[index];
-        }
-        return 0;
-    }
-
-    void setUserInt(unsigned int index, int32_t value) {
-        if (index < ISMRMRD_USER_INTS) {
-            head_.user_int[index] = value;
-        }
-    }
-
-    uint16_t getVersion() const {
-        return head_.version;
-    }
-
-    void setVersion(uint16_t version) {
-        this->head_.version = version;
-    }
-
-    const std::valarray<T>& getData() const {
-        return data_;
-    }
-
-    void setData(const std::valarray<T>& data) {
-        data_ = data;
-    }
-
-    const ImageHeader& getHead() const {
-        return head_;
-    }
-
-    void setHead(const ImageHeader& head) {
-        head_ = head;
-        makeConsistent();
-    }
-
-    T& operator[] (const size_t& p) {
-        return data_[p];
-    }
-
-    T operator[] (const size_t& p) const {
-        return data_[p];
-    }
-
-
-protected:
-    ImageHeader head_;     /**< ImageHeader as defined above */
-    std::valarray<T> data_;
-    void makeConsistent() {
-        if (getNumberOfElements() != data_.size()) {
-            data_.resize(getNumberOfElements());
-        }
-    }
-
-    void setSpecificDataType();
-
-};
-
-template <> inline void Image<float>::setSpecificDataType() {
-    head_.image_data_type = DATA_FLOAT;
-}
-
-template <> inline void Image<double>::setSpecificDataType() {
-    head_.image_data_type = DATA_DOUBLE;
-}
-
-template <> inline void Image< std::complex<float> >::setSpecificDataType() {
-    head_.image_data_type = DATA_COMPLEX_FLOAT;
-}
-
-template <> inline void Image< std::complex<double> >::setSpecificDataType() {
-    head_.image_data_type = DATA_COMPLEX_DOUBLE;
-}
-
-template <> inline void Image< unsigned short >::setSpecificDataType() {
-    head_.image_data_type = DATA_UNSIGNED_SHORT;
-}
-
-
-
-/**
- * @brief Single acquisition
- */
-
-/* TODO:
- *    - Move data and traj to protected
- *    - Check data and traj sizes when assigning number of samples, active channels, traj dimensions
- *    - Check active channels when assigning channel bits
- *    - Assign channel bits when assiging number of channels
- *    - Change Image to have encapsulation
- *    - Make Image Data Type Consistent with field.
- *    - Test, test, test.
- */
-class Acquisition {
-
-public:
-    Acquisition()
-        : traj_(), data_() {
-        memset(&head_,0,sizeof(AcquisitionHeader));
-        head_.version = ISMRMRD_VERSION;
-    }
-
-    ~Acquisition() {}
-
-    Acquisition (const Acquisition& a) {   // copy constructor
-        if (this != &a) {
-            head_ = a.head_;
-            data_.resize(a.data_.size());
-            memcpy(&data_[0],&a.data_[0],sizeof(float)*a.data_.size());
-            traj_.resize(a.traj_.size());
-            memcpy(&traj_[0],&a.traj_[0],sizeof(float)*a.traj_.size());
-        }
-    }
-
-    Acquisition& operator=(const Acquisition& a) {
-        if (this != &a) {
-            head_ = a.head_;
-            data_.resize(a.data_.size());
-            memcpy(&data_[0],&a.data_[0],sizeof(float)*a.data_.size());
-            traj_.resize(a.traj_.size());
-            memcpy(&traj_[0],&a.traj_[0],sizeof(float)*a.traj_.size());
-        }
-        return *this;
-    }
-
-    const AcquisitionHeader& getHead() {
-        return head_;
-    }
-
-    void setHead(const AcquisitionHeader& h) {
-        head_ = h;
-        makeConsistent();
-    }
-
-    bool isFlagSet(const FlagBit& f) const {
-        return f.isSet(head_.flags);
-    }
-
-    void setFlag(const FlagBit& f) {
-        head_.flags |= f.bitmask_;
-    }
-
-    uint32_t getAcquisitionTimeStamp() const {
-        return head_.acquisition_time_stamp;
-    }
-
-    void setAcquisitionTimeStamp(uint32_t acquisitionTimeStamp) {
-        head_.acquisition_time_stamp = acquisitionTimeStamp;
-    }
-
-    uint16_t getActiveChannels() const {
-        return head_.active_channels;
-    }
-
-    void setActiveChannels(uint16_t activeChannels) {
-        head_.active_channels = activeChannels;
-        makeConsistent();
-    }
-
-    uint16_t getAvailableChannels() const {
-        return head_.available_channels;
-    }
-
-    void setAvailableChannels(uint16_t availableChannels) {
-        head_.available_channels = availableChannels;
-    }
-
-    uint16_t getCenterSample() const {
-        return head_.center_sample;
-    }
-
-    void setCenterSample(uint16_t centerSample) {
-        head_.center_sample = centerSample;
-    }
-
-    bool isChannelActive(unsigned int channel_id) {
-        if (channel_id < 64*ISMRMRD_CHANNEL_MASKS) {
-            unsigned int mask_idx = channel_id>>6;
-            unsigned int mask_bit = channel_id-mask_idx*64;
-            return ((head_.channel_mask[mask_idx] & ( (uint64_t)1 << mask_bit)) > 0);
-        }
-        return false;
-    }
-
-    void setChannelActive(unsigned int channel_id) {
-        if (channel_id < 64*ISMRMRD_CHANNEL_MASKS) {
-            unsigned int mask_idx = channel_id>>6;
-            unsigned int mask_bit = channel_id-mask_idx*64;
-            head_.channel_mask[mask_idx] |= ( (uint64_t)1 << mask_bit);
-        }
-    }
-
-    unsigned int getActiveChannelBits() {
-        unsigned int bits = 0;
-        for (unsigned int i = 0; i < ISMRMRD_CHANNEL_MASKS*64; i++) {
-            if (isChannelActive(i)) {
-                bits++;
-            }
-        }
-        return bits;
-    }
-
-    uint16_t getDiscardPost() const {
-        return head_.discard_post;
-    }
-
-    void setDiscardPost(uint16_t discardPost) {
-        head_.discard_post = discardPost;
-    }
-
-    uint16_t getDiscardPre() const {
-        return head_.discard_pre;
-    }
-
-    void setDiscardPre(uint16_t discardPre) {
-        head_.discard_pre = discardPre;
-    }
-
-    uint16_t getEncodingSpaceRef() const {
-        return head_.encoding_space_ref;
-    }
-
-    void setEncodingSpaceRef(uint16_t encodingSpaceRef) {
-        head_.encoding_space_ref = encodingSpaceRef;
-    }
-
-    uint64_t getFlags() const {
-        return head_.flags;
-    }
-
-    void setFlags(uint64_t flags) {
-        this->head_.flags = flags;
-    }
-
-    EncodingCounters& getIdx() {
-        return head_.idx;
-    }
-
-    void setIdx(const EncodingCounters& idx) {
-        this->head_.idx = idx;
-    }
-
-    uint32_t getMeasurementUid() const {
-        return head_.measurement_uid;
-    }
-
-    void setMeasurementUid(uint32_t measurementUid) {
-        head_.measurement_uid = measurementUid;
-    }
-
-    uint16_t getNumberOfSamples() const {
-        return head_.number_of_samples;
-    }
-
-    void setNumberOfSamples(uint16_t numberOfSamples) {
-        head_.number_of_samples = numberOfSamples;
-        makeConsistent();
-    }
-
-    const float getPatientTablePosition(unsigned int axis) const {
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            return head_.patient_table_position[axis];
-        }
-        return 0;
-    }
-
-    void setPatientTablePosition(unsigned int axis, float value) {
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            head_.patient_table_position[axis] = value;
-        }
-    }
-
-    const uint32_t getPhysiologyTimeStamp(unsigned int stamp_id) const {
-        if (stamp_id < ISMRMRD_PHYS_STAMPS) {
-            return head_.physiology_time_stamp[stamp_id];
-        }
-        return 0;
-    }
-
-    void setPhysiologyTimeStamp(unsigned int stamp_id, uint32_t value){
-        if (stamp_id < ISMRMRD_PHYS_STAMPS) {
-            head_.physiology_time_stamp[stamp_id] = value;
-        }
-    }
-
-    const float getPosition(unsigned int axis) const {
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            return head_.position[axis];
-        }
-        return 0;
-    }
-
-    void setPosition(unsigned int axis, float value){
-        if (axis < ISMRMRD_POSITION_LENGTH) {
-            head_.position[axis] = value;
-        }
-    }
-
-        const float getReadDirection(unsigned int index) const {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        return head_.read_dir[index];
-                }
-                return 0;
-        }
-
-        void setReadDirection(unsigned int index, float value) {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        head_.read_dir[index] = value;
-                }
-        }
-
-        const float getPhaseDirection(unsigned int index) const {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        return head_.phase_dir[index];
-                }
-                return 0;
-        }
-
-        void setPhaseDirection(unsigned int index, float value) {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        head_.phase_dir[index] = value;
-                }
-        }
-
-        const float getSliceDirection(unsigned int index) const {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        return head_.slice_dir[index];
-                }
-                return 0;
-        }
-
-        void setSliceDirection(unsigned int index, float value) {
-                if (index < ISMRMRD_DIRECTION_LENGTH) {
-                        head_.slice_dir[index] = value;
-                }
-        }
-
-    float getSampleTimeUs() const {
-        return head_.sample_time_us;
-    }
-
-    void setSampleTimeUs(float sampleTimeUs) {
-        head_.sample_time_us = sampleTimeUs;
-    }
-
-    uint32_t getScanCounter() const {
-        return head_.scan_counter;
-    }
-
-    void setScanCounter(uint32_t scanCounter) {
-        head_.scan_counter = scanCounter;
-    }
-
-    uint16_t getTrajectoryDimensions() const {
-        return head_.trajectory_dimensions;
-    }
-
-    void setTrajectoryDimensions(uint16_t trajectoryDimensions) {
-        head_.trajectory_dimensions = trajectoryDimensions;
-        makeConsistent();
-    }
-
-    const float getUserFloat(unsigned int index) const {
-        if (index < ISMRMRD_USER_FLOATS) {
-            return head_.user_float[index];
-        }
-        return 0.0f;
-    }
-
-    void setUserFloat(unsigned int index, float value) {
-        if (index < ISMRMRD_USER_FLOATS) {
-            head_.user_float[index] = value;
-        }
-    }
-
-    const int32_t getUserInt(unsigned int index) const {
-        if (index < ISMRMRD_USER_INTS) {
-            return head_.user_int[index];
-        }
-        return 0;
-    }
-
-    void setUserInt(unsigned int index, int32_t value) {
-        if (index < ISMRMRD_USER_INTS) {
-            head_.user_int[index] = value;
-        }
-    }
-
-    uint16_t getVersion() const {
-        return head_.version;
-    }
-
-    void setVersion(uint16_t version) {
-        this->head_.version = version;
-    }
-
-    const std::valarray<float>& getData() const {
-        return data_;
-    }
-
-    void setData(const std::valarray<float>& data) {
-        data_ = data;
-    }
-
-    const std::valarray<float>& getTraj() const {
-        return traj_;
-    }
-
-    void setTraj(const std::valarray<float>& traj) {
-        traj_ = traj;
-    }
-
-    float& operator[] (const size_t& p) {
-        return data_[p];
-    }
-
-    float operator[] (const size_t& p) const {
-        return data_[p];
-    }
-
-protected:
-    size_t calcTrajLength() {
-        return head_.trajectory_dimensions*head_.number_of_samples;
-    }
-
-    size_t calcDataLength() {
-        return head_.active_channels*head_.number_of_samples*2;
-    }
-
-
-    void makeConsistent() {
-        if (head_.active_channels > head_.available_channels) {
-            head_.available_channels = head_.active_channels;
-        }
-        if (calcTrajLength() != traj_.size()) {
-            traj_.resize(calcTrajLength());
-        }
-        if (calcDataLength() != data_.size()) {
-            data_.resize(calcDataLength());
-        }
-    }
-
-    AcquisitionHeader head_; /**< Header, see above */
-    std::valarray<float> traj_;
-    std::valarray<float> data_;
-
-};
-
-#endif //__cplusplus
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**
- * Calculates the determinant of the matrix and return the sign
- */
-static int sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3])
-{
-    float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
-    float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
-    float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
-
-    /* Determinant should be 1 or -1 */
-    float deti = (r11 * r22 * r33) + (r12 * r23 * r31) + (r21 * r32 * r13) -
-                 (r13 * r22 * r31) - (r12 * r21 * r33) - (r11 * r23 * r32);
-
-    if (deti < 0) {
-        return -1;
-    } else {
-        return 1;
-    }
-}
-
-/**
- * Creates a normalized quaternion from a 3x3 rotation matrix
- */
-static void directions_to_quaternion(float read_dir[3], float phase_dir[3],
-        float slice_dir[3], float quat[4])
-{
-    float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
-    float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
-    float r31 = read_dir[2], r32 = phase_dir[2], r33 = slice_dir[2];
-
-    double a = 1, b = 0, c = 0, d = 0, s = 0;
-    double trace = 0;
-    double xd, yd, zd;
-
-    /* verify the sign of the rotation*/
-    if (sign_of_directions(read_dir, phase_dir, slice_dir) < 0) {
-        /* flip 3rd column */
-        r13 = -r13;
-        r23 = -r23;
-        r33 = -r33;
-    }
-
-    /* Compute quaternion parameters */
-    /* http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q55 */
-    trace = 1.0l + r11 + r22 + r33;
-    if (trace > 0.00001l) {                /* simplest case */
-        s = sqrt(trace) * 2;
-        a = (r32 - r23) / s;
-        b = (r13 - r31) / s;
-        c = (r21 - r12) / s;
-        d = 0.25l * s;
-    } else {
-        /* trickier case...
-         * determine which major diagonal element has
-         * the greatest value... */
-        xd = 1.0 + r11 - (r22 + r33);  /* 4**b**b */
-        yd = 1.0 + r22 - (r11 + r33);  /* 4**c**c */
-        zd = 1.0 + r33 - (r11 + r22);  /* 4**d**d */
-        /* if r11 is the greatest */
-        if (xd > 1.0) {
-            s = 2.0 * sqrt(xd);
-            a = 0.25l * s;
-            b = (r21 + r12) / s;
-            c = (r31 + r13) / s;
-            d = (r32 - r23) / s;
-        }
-        /* else if r22 is the greatest */
-        else if (yd > 1.0) {
-            s = 2.0 * sqrt(yd);
-            a = (r21 + r12) / s;
-            b = 0.25l * s;
-            c = (r32 + r23) / s;
-            d = (r13 - r31) / s;
-        }
-        /* else, r33 must be the greatest */
-        else {
-            s = 2.0 * sqrt(zd);
-            a = (r13 + r31) / s;
-            b = (r23 + r32) / s;
-            c = 0.25l * s;
-            d = (r21 - r12) / s;
-        }
-
-        if (a < 0.0l) {
-            b = -b;
-            c = -c;
-            d = -d;
-            a = -a;
-        }
-    }
-
-    quat[0] = (float)a; quat[1] = (float)b; quat[2] = (float)c; quat[3] = (float)d;
-}
-
-/**
- * Converts a quaternion of the form | a b c d | to a
- * 3x3 rotation matrix
- *
- * http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q54
- */
-static void quaternion_to_directions(float quat[4], float read_dir[3],
-        float phase_dir[3], float slice_dir[3])
-{
-    float a = quat[0], b = quat[1], c = quat[2], d = quat[3];
-
-    read_dir[0]  = 1.0f - 2.0f * ( b*b + c*c );
-    phase_dir[0] = 2.0f * ( a*b - c*d );
-    slice_dir[0] = 2.0f * ( a*c + b*d );
-
-    read_dir[1]  = 2.0f * ( a*b + c*d );
-    phase_dir[1] = 1.0f - 2.0f * ( a*a + c*c );
-    slice_dir[1] = 2.0f * ( b*c - a*d );
-
-    read_dir[2]  = 2.0f * ( a*c - b*d );
-    phase_dir[2] = 2.0f * ( b*c + a*d );
-    slice_dir[2] = 1.0f - 2.0f * ( a*a + b*b );
-}
-
-#ifdef __cplusplus
-}
-#endif
+typedef struct Image {
+  ImageHeader head;
+  void* data;
+  char* attribute_string;
+} Image;
+
+void initImage(Image* im);
+void freeImage(Image* im);
+void makeConsistentImage(Image* im);
+
+/************/
+/* NDArrays */
+/************/
+
+typedef struct NDArray {
+  uint16_t version;   /**< First unsigned int indicates the version */
+  uint16_t data_type; /**< e.g. unsigned short, float, complex float, etc. */
+  uint16_t ndim;      /**< Number of dimensions */
+  uint16_t dims[ISMRMRD_NDARRAY_MAXDIM]; /**< Dimensions */
+  void* data;                            /**< pointer to data array */
+} NDArray;
+
+void initNDArray(NDArray* arr);
+void freeNDArray(NDArray* arr);
+void makeConsistentNDArray(NDArray* arr);
+
+/*********/
+/* Flags */
+/*********/
+bool flags_is_set(const uint64_t flags, const uint64_t val);
+void flags_set(uint64_t* flags, const uint64_t val);
+void flags_clear(uint64_t* flags, const uint64_t val);
+void flags_clear_all(uint64_t* flags);
+
+/*****************************/
+/* Rotations and Quaternions */
+/*****************************/
+/* Calculates the determinant of the matrix and return the sign */
+intsign_of_directions(float read_dir[3], float phase_dir[3],
+                      float slice_dir[3]);
+
+/* Creates a normalized quaternion from a 3x3 rotation matrix */
+voiddirections_to_quaternion(float read_dir[3], float phase_dir[3],
+                             float slice_dir[3], float quat[4]);
+
+/* Converts a quaternion of the form | a b c d | to a 3x3 rotation matrix */
+voidquaternion_to_directions(float quat[4], float read_dir[3],
+                             float phase_dir[3], float slice_dir[3]);
 
 #ifdef __cplusplus
-} //End of ISMRMRD namespace
-#endif //__cplusplus
+}  // End of ISMRMRD namespace
+#endif  //__cplusplus
 
-#pragma pack(pop) //Restore old alignment
+#pragma pack(pop)  // Restore old alignment
 
-#endif //ISMRMRD_H
+#endif  // ISMRMRD_H
diff --git a/ismrmrd_hdf5.h b/ismrmrd_hdf5.h
index 75e733b..3e29858 100644
--- a/ismrmrd_hdf5.h
+++ b/ismrmrd_hdf5.h
@@ -14,11 +14,11 @@
 #include <boost/thread.hpp>
 
 
-#include <H5Cpp.h>
+#include <hdf5.h>
 
-#ifndef H5_NO_NAMESPACE
-using namespace H5;
-#endif
+//#ifndef H5_NO_NAMESPACE
+//using namespace H5;
+//#endif
 
 
 namespace ISMRMRD
diff --git a/ismrmrd_hdf5_datatypes.h b/ismrmrd_hdf5_datatypes.h
index 09e3e69..c57df8f 100644
--- a/ismrmrd_hdf5_datatypes.h
+++ b/ismrmrd_hdf5_datatypes.h
@@ -4,7 +4,7 @@
 
 #include "ismrmrd.h"
 
-#include <H5Cpp.h>
+#include <hdf5.h>
 #include <boost/shared_ptr.hpp>
 
 
@@ -12,9 +12,9 @@
 #include <complex>
 #include <string>
 
-#ifndef H5_NO_NAMESPACE
-	using namespace H5;
-#endif
+//#ifndef H5_NO_NAMESPACE
+//	using namespace H5;
+//#endif
 
 namespace ISMRMRD
 {
@@ -121,43 +121,43 @@ namespace ISMRMRD
   
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint16_t, 3 >() {
     std::vector<hsize_t> dims(1,3);
-    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0]);
     return t;
   }
 
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint16_t, ISMRMRD_USER_INTS >() {
     std::vector<hsize_t> dims(1,ISMRMRD_USER_INTS);
-    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT16, 1, &dims[0]);
     return t;
   }
 
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint32_t, 3 >() { //TODO: The 3 should be replace with ISMRMRD_PHYS_TIME_STAMPS when that is corrected
     std::vector<hsize_t> dims(1,3);//TODO: Replace when header is updated
-    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT32, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT32, 1, &dims[0]);
     return t;
   }
 
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< int32_t, ISMRMRD_USER_INTS >() {
     std::vector<hsize_t> dims(1,ISMRMRD_USER_INTS);
-    hid_t t  = H5Tarray_create(H5T_NATIVE_INT32, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_INT32, 1, &dims[0]);
     return t;
   }
 
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< uint64_t, ISMRMRD_CHANNEL_MASKS >() {
     std::vector<hsize_t> dims(1,ISMRMRD_CHANNEL_MASKS);
-    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT64, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_UINT64, 1, &dims[0]);
     return t;
   }
 
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< float, ISMRMRD_POSITION_LENGTH >() {
     std::vector<hsize_t> dims(1,ISMRMRD_POSITION_LENGTH);
-    hid_t t  = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0]);
     return t;
   }
   
   template <> inline hid_t  IsmrmrdHDF5TypeContainer::getIsmrmrdHDF5ArrayType< float, ISMRMRD_USER_FLOATS >() {
     std::vector<hsize_t> dims(1,ISMRMRD_USER_FLOATS);
-    hid_t t  = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0], NULL);
+    hid_t t  = H5Tarray_create(H5T_NATIVE_FLOAT, 1, &dims[0]);
     return t;
   }
 
@@ -343,327 +343,4 @@ namespace ISMRMRD
   }
   /* HDF5 C Interface (end) */
 
-template <typename T> boost::shared_ptr<DataType> getIsmrmrdHDF5Type();
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<float>()
-{
-	boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_FLOAT)));
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<double>()
-{
-	boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_DOUBLE)));
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<char>()
-{
-	boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_CHAR)));
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type< std::complex<float> >()
-{
-	CompType* ct = new CompType(sizeof( std::complex<float> ));
-	ct->insertMember( "real",  0,              PredType::NATIVE_FLOAT);
-	ct->insertMember( "imag",  sizeof(float),  PredType::NATIVE_FLOAT);
-	boost::shared_ptr<DataType> ret(ct);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type< std::complex<double> >()
-{
-	CompType* ct = new CompType(sizeof( std::complex<double> ));
-	ct->insertMember( "real",  0,              PredType::NATIVE_DOUBLE);
-	ct->insertMember( "imag",  sizeof(double), PredType::NATIVE_DOUBLE);
-	boost::shared_ptr<DataType> ret(ct);
-	return ret;
-}
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type< unsigned short >()
-{
-	boost::shared_ptr<DataType> ret(new DataType(H5Tcopy(H5T_NATIVE_USHORT)));
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<EncodingCounters>()
-{
-
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(EncodingCounters)));
-
-	ret->insertMember( "kspace_encode_step_1", 	HOFFSET(EncodingCounters, kspace_encode_step_1), PredType::NATIVE_UINT16);
-	ret->insertMember( "kspace_encode_step_2", 	HOFFSET(EncodingCounters, kspace_encode_step_2), PredType::NATIVE_UINT16);
-	ret->insertMember( "average", 				HOFFSET(EncodingCounters, average), 				PredType::NATIVE_UINT16);
-	ret->insertMember( "slice", 				HOFFSET(EncodingCounters, slice), 				PredType::NATIVE_UINT16);
-	ret->insertMember( "contrast", 				HOFFSET(EncodingCounters, contrast), 			PredType::NATIVE_UINT16);
-	ret->insertMember( "phase", 				HOFFSET(EncodingCounters, phase), 				PredType::NATIVE_UINT16);
-	ret->insertMember( "repetition", 			HOFFSET(EncodingCounters, repetition), 			PredType::NATIVE_UINT16);
-	ret->insertMember( "set", 					HOFFSET(EncodingCounters, set), 					PredType::NATIVE_UINT16);
-	ret->insertMember( "segment", 				HOFFSET(EncodingCounters, segment), 				PredType::NATIVE_UINT16);
-
-	std::vector<hsize_t> dims(1,8);
-	boost::shared_ptr<DataType> array_type(new ArrayType(PredType::NATIVE_UINT16, 1, &dims[0]));
-	ret->insertMember( "user", 					HOFFSET(EncodingCounters, user), 				*array_type);
-
-	return ret;
-};
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<AcquisitionHeader>()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(AcquisitionHeader)));
-	ret->insertMember( "version", 					HOFFSET(AcquisitionHeader, version), 				PredType::NATIVE_UINT16);
-	ret->insertMember( "flags", 					HOFFSET(AcquisitionHeader, flags), 					PredType::NATIVE_UINT64);
-	ret->insertMember( "measurement_uid", 			HOFFSET(AcquisitionHeader, measurement_uid), 		PredType::NATIVE_UINT32);
-	ret->insertMember( "scan_counter", 				HOFFSET(AcquisitionHeader, scan_counter), 			PredType::NATIVE_UINT32);
-	ret->insertMember( "acquisition_time_stamp", 	HOFFSET(AcquisitionHeader, acquisition_time_stamp), PredType::NATIVE_UINT32);
-
-        // TODO: change ISMRMRD_PHYS_STAMPS to 3 (Major change)
-        // we should use the size defines and not hard coded numbers.
-	std::vector<hsize_t> dims(1,3);
-	boost::shared_ptr<DataType> array_type(new ArrayType(PredType::NATIVE_UINT32, 1, &dims[0]));
-	ret->insertMember( "physiology_time_stamp", HOFFSET(AcquisitionHeader, physiology_time_stamp), 		*array_type);
-
-	ret->insertMember( "number_of_samples", 		HOFFSET(AcquisitionHeader, number_of_samples), 		PredType::NATIVE_UINT16);
-	ret->insertMember( "available_channels", 		HOFFSET(AcquisitionHeader, available_channels), 	PredType::NATIVE_UINT16);
-	ret->insertMember( "active_channels", 			HOFFSET(AcquisitionHeader, active_channels), 		PredType::NATIVE_UINT16);
-
-	dims[0] = 16;
-	boost::shared_ptr<DataType> mask_array_type(new ArrayType(PredType::NATIVE_UINT64, 1, &dims[0]));
-	ret->insertMember( "channel_mask", 				HOFFSET(AcquisitionHeader, channel_mask), 			*mask_array_type);
-	ret->insertMember( "discard_pre", 				HOFFSET(AcquisitionHeader, discard_pre), 			PredType::NATIVE_UINT16);
-	ret->insertMember( "discard_post", 				HOFFSET(AcquisitionHeader, discard_post), 			PredType::NATIVE_UINT16);
-	ret->insertMember( "center_sample", 			HOFFSET(AcquisitionHeader, center_sample), 			PredType::NATIVE_UINT16);
-	ret->insertMember( "encoding_space_ref", 		HOFFSET(AcquisitionHeader, encoding_space_ref), 	PredType::NATIVE_UINT16);
-	ret->insertMember( "trajectory_dimensions",		HOFFSET(AcquisitionHeader, trajectory_dimensions), 	PredType::NATIVE_UINT16);
-	ret->insertMember( "sample_time_us", 			HOFFSET(AcquisitionHeader, sample_time_us), 		PredType::NATIVE_FLOAT);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> position_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "position", 					HOFFSET(AcquisitionHeader, position), 				*position_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> read_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "read_dir", 				HOFFSET(AcquisitionHeader, read_dir), 			*read_dir_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> phase_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "phase_dir", 				HOFFSET(AcquisitionHeader, phase_dir), 			*phase_dir_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> slice_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "slice_dir", 				HOFFSET(AcquisitionHeader, slice_dir), 			*slice_dir_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> table_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "patient_table_position", 	HOFFSET(AcquisitionHeader, patient_table_position), *table_array_type);
-
-	boost::shared_ptr<DataType>  ec_type = getIsmrmrdHDF5Type<EncodingCounters>();
-	ret->insertMember( "idx", 						HOFFSET(AcquisitionHeader, idx), 					*ec_type);
-
-	dims[0] = 8;
-	boost::shared_ptr<DataType> user_int_array_type(new ArrayType(PredType::NATIVE_INT32, 1, &dims[0]));
-	ret->insertMember( "user_int", 					HOFFSET(AcquisitionHeader, user_int), 				*user_int_array_type);
-
-	dims[0] = 8;
-	boost::shared_ptr<DataType> user_float_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "user_float", 					HOFFSET(AcquisitionHeader, user_float), 		*user_float_array_type);
-
-	return ret;
-
-}
-
-
-struct complex_t
-{
-	float real;
-	float imag;
-};
-
-struct double_complex_t
-{
-	double real;
-	double imag;
-};
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<complex_t>()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(complex_t)));
-	ret->insertMember( "real",  HOFFSET(complex_t,real),   PredType::NATIVE_FLOAT);
-	ret->insertMember( "imag",  HOFFSET(complex_t,imag),   PredType::NATIVE_FLOAT);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<double_complex_t>()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(double_complex_t)));
-	ret->insertMember( "real",  HOFFSET(complex_t,real),   PredType::NATIVE_DOUBLE);
-	ret->insertMember( "imag",  HOFFSET(complex_t,imag),   PredType::NATIVE_DOUBLE);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<AcquisitionHeader_with_data>()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(AcquisitionHeader_with_data)));
-
-	boost::shared_ptr<DataType>  head_type = getIsmrmrdHDF5Type<AcquisitionHeader>();
-	//boost::shared_ptr<DataType> cxvdatatype = getIsmrmrdHDF5Type<complex_t>();
-	//cxvdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (cxvdatatype->getId())));
-	boost::shared_ptr<DataType> realvdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (PredType::NATIVE_FLOAT.getId())));
-
-	ret->insertMember( "head",  HOFFSET(AcquisitionHeader_with_data,head),   	*head_type);
-	ret->insertMember( "traj", HOFFSET(AcquisitionHeader_with_data,traj),  		*realvdatatype);
-	ret->insertMember( "data", HOFFSET(AcquisitionHeader_with_data,data),  		*realvdatatype);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader>()
-{
-
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader)));
-
-	ret->insertMember( "version", 					HOFFSET(ImageHeader, version), 					PredType::NATIVE_UINT16);
-	ret->insertMember( "flags", 					HOFFSET(ImageHeader, flags), 				   	PredType::NATIVE_UINT64);
-	ret->insertMember( "measurement_uid", 			HOFFSET(ImageHeader, measurement_uid), 		    PredType::NATIVE_UINT32);
-
-	std::vector<hsize_t> dims(1,0);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> mat_size_array_type(new ArrayType(PredType::NATIVE_UINT16, 1, &dims[0]));
-	ret->insertMember( "matrix_size", 				HOFFSET(ImageHeader, matrix_size), 		*mat_size_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> fov_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "field_of_view", 			HOFFSET(ImageHeader, field_of_view), 		*fov_array_type);
-
-	ret->insertMember( "channels", 					HOFFSET(ImageHeader, channels), 					PredType::NATIVE_UINT16);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> position_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "position", 					HOFFSET(ImageHeader, position), 				*position_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> read_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "read_dir", 				HOFFSET(ImageHeader, read_dir), 			*read_dir_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> phase_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "phase_dir", 				HOFFSET(ImageHeader, phase_dir), 			*phase_dir_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> slice_dir_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "slice_dir", 				HOFFSET(ImageHeader, slice_dir), 			*slice_dir_array_type);
-
-	dims[0] = 3;
-	boost::shared_ptr<DataType> table_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "patient_table_position", 	HOFFSET(ImageHeader, patient_table_position), *table_array_type);
-
-
-	ret->insertMember( "average", 					HOFFSET(ImageHeader, average), 					PredType::NATIVE_UINT16);
-	ret->insertMember( "slice", 					HOFFSET(ImageHeader, slice), 					PredType::NATIVE_UINT16);
-	ret->insertMember( "contrast", 					HOFFSET(ImageHeader, contrast), 				PredType::NATIVE_UINT16);
-	ret->insertMember( "phase", 					HOFFSET(ImageHeader, phase), 					PredType::NATIVE_UINT16);
-	ret->insertMember( "repetition", 				HOFFSET(ImageHeader, repetition), 				PredType::NATIVE_UINT16);
-	ret->insertMember( "set",   					HOFFSET(ImageHeader, set), 						PredType::NATIVE_UINT16);
-	ret->insertMember( "acquisition_time_stamp", 	HOFFSET(ImageHeader, acquisition_time_stamp),   PredType::NATIVE_UINT32);
-
-        // TODO: ISMRMRD_PHYS_STAMPS should be 3 (Major change)
-        // we should use the size defines and not hard coded numbers.
-	dims[0] = 3;
-	boost::shared_ptr<DataType> array_type(new ArrayType(PredType::NATIVE_UINT32, 1, &dims[0]));
-	ret->insertMember( "physiology_time_stamp", HOFFSET(ImageHeader, physiology_time_stamp), 		*array_type);
-
-	ret->insertMember( "image_data_type",   		HOFFSET(ImageHeader, image_data_type),			PredType::NATIVE_UINT16);
-	ret->insertMember( "image_type",   				HOFFSET(ImageHeader, image_type),				PredType::NATIVE_UINT16);
-	ret->insertMember( "image_index",   			HOFFSET(ImageHeader, image_index),				PredType::NATIVE_UINT16);
-	ret->insertMember( "image_series_index",		HOFFSET(ImageHeader, image_series_index),		PredType::NATIVE_UINT16);
-
-	dims[0] = 8;
-	boost::shared_ptr<DataType> user_int_array_type(new ArrayType(PredType::NATIVE_INT32, 1, &dims[0]));
-	ret->insertMember( "user_int", 				HOFFSET(ImageHeader, user_int), *user_int_array_type);
-
-	dims[0] = 8;
-	boost::shared_ptr<DataType> user_float_array_type(new ArrayType(PredType::NATIVE_FLOAT, 1, &dims[0]));
-	ret->insertMember( "user_float", 				HOFFSET(ImageHeader, user_float), *user_float_array_type);
-
-	return ret;
-}
-
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<float> >()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<float>)));
-	boost::shared_ptr<DataType>  head_type = getIsmrmrdHDF5Type<ImageHeader>();
-	boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<float>();
-	vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
-	ret->insertMember( "head",  HOFFSET(ImageHeader_with_data<float>,head),   	*head_type);
-	ret->insertMember( "data", HOFFSET(ImageHeader_with_data<float>,data),  	*vdatatype);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<double> >()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<double>)));
-	boost::shared_ptr<DataType>  head_type = getIsmrmrdHDF5Type<ImageHeader>();
-	boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<double>();
-	vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
-	ret->insertMember( "head",  HOFFSET(ImageHeader_with_data<double>,head),   	*head_type);
-	ret->insertMember( "data", HOFFSET(ImageHeader_with_data<double>,data),  	*vdatatype);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<unsigned short> >()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<unsigned short>)));
-	boost::shared_ptr<DataType>  head_type = getIsmrmrdHDF5Type<ImageHeader>();
-	boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<unsigned short>();
-	vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
-	ret->insertMember( "head",  HOFFSET(ImageHeader_with_data<unsigned short>,head),   	*head_type);
-	ret->insertMember( "data", HOFFSET(ImageHeader_with_data<unsigned short>,data),  	*vdatatype);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<complex_t> >()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<complex_t>)));
-	boost::shared_ptr<DataType>  head_type = getIsmrmrdHDF5Type<ImageHeader>();
-	boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<complex_t>();
-	vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
-	ret->insertMember( "head",  HOFFSET(ImageHeader_with_data<complex_t>,head),   	*head_type);
-	ret->insertMember( "data", HOFFSET(ImageHeader_with_data<complex_t>,data),  	*vdatatype);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data<double_complex_t> >()
-{
-	boost::shared_ptr<CompType> ret = boost::shared_ptr<CompType>(new CompType(sizeof(ImageHeader_with_data<double_complex_t>)));
-	boost::shared_ptr<DataType>  head_type = getIsmrmrdHDF5Type<ImageHeader>();
-	boost::shared_ptr<DataType> vdatatype = getIsmrmrdHDF5Type<double_complex_t>();
-	vdatatype = boost::shared_ptr<DataType>(new DataType(H5Tvlen_create (vdatatype->getId())));
-	ret->insertMember( "head",  HOFFSET(ImageHeader_with_data<double_complex_t>,head),   	*head_type);
-	ret->insertMember( "data", HOFFSET(ImageHeader_with_data<double_complex_t>,data),  	*vdatatype);
-	return ret;
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data< std::complex<float> > >()
-{
-	return getIsmrmrdHDF5Type<ImageHeader_with_data<complex_t> >();
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<ImageHeader_with_data< std::complex<double> > >()
-{
-	return getIsmrmrdHDF5Type<ImageHeader_with_data<double_complex_t> >();
-}
-
-template <> inline boost::shared_ptr<DataType> getIsmrmrdHDF5Type<std::string>()
-{
-	boost::shared_ptr<DataType> ret(new StrType(0, H5T_VARIABLE));
-	return ret;
-}
-
-}
-
 #endif /* ISMRMRD_HDF5_DATATYPES_H_ */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ismrmrd.git



More information about the debian-science-commits mailing list