[ismrmrd] 08/177: Added namespace-like protection around C interface. Beginning to build up C++ interface.
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:01:56 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 2f9c46d793c58788ce8b3096e046014eea7a29ab
Author: Souheil Inati <souheil.inati at nih.gov>
Date: Tue Jul 22 09:20:11 2014 -0400
Added namespace-like protection around C interface. Beginning to build up C++ interface.
---
_clang-format | 48 ++++
ismrmrd.c | 648 ++++++++++++++++++++++-------------------------
ismrmrd.cpp | 69 +++++
ismrmrd.h | 449 ++++++++++++++++----------------
ismrmrd.hpp | 59 +++++
tests/c++/basic_test.cpp | 35 +++
tests/c/basic_test.c | 32 +--
7 files changed, 749 insertions(+), 591 deletions(-)
diff --git a/_clang-format b/_clang-format
new file mode 100644
index 0000000..384dfe2
--- /dev/null
+++ b/_clang-format
@@ -0,0 +1,48 @@
+---
+# BasedOnStyle: LLVM
+AccessModifierOffset: -4
+ConstructorInitializerIndentWidth: 4
+AlignEscapedNewlinesLeft: false
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakTemplateDeclarations: false
+AlwaysBreakBeforeMultilineStrings: false
+BreakBeforeBinaryOperators: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BinPackParameters: true
+ColumnLimit: 0
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+DerivePointerBinding: false
+ExperimentalAutoDetectBinPacking: false
+IndentCaseLabels: false
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 60
+PenaltyBreakString: 1000
+PenaltyBreakFirstLessLess: 120
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerBindsToType: false
+SpaceBeforeAssignmentOperators: true
+SpacesBeforeTrailingComments: 1
+Cpp11BracedListStyle: false
+Standard: Cpp03
+IndentWidth: 4
+TabWidth: 4
+UseTab: Never
+BreakBeforeBraces: Attach
+IndentFunctionDeclarationAfterType: false
+SpacesInParentheses: false
+SpacesInAngles: false
+SpaceInEmptyParentheses: false
+SpacesInCStyleCastParentheses: false
+SpaceAfterControlStatementKeyword: true
+SpaceBeforeAssignmentOperators: true
+ContinuationIndentWidth: 4
+...
+
diff --git a/ismrmrd.c b/ismrmrd.c
index e64b854..1a9a241 100644
--- a/ismrmrd.c
+++ b/ismrmrd.c
@@ -1,382 +1,342 @@
-#include <ismrmrd.h>
+#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;
+void ismrmrd_init_acquisition_header(ISMRMRD_AcquisitionHeader *hdr) {
+ memset(hdr, 0, sizeof(ISMRMRD_AcquisitionHeader));
+ hdr->version = ISMRMRD_VERSION;
+ hdr->number_of_samples = 0;
+ hdr->available_channels = 1;
+ hdr->active_channels = 1;
+}
+
+void ismrmrd_init_acquisition(ISMRMRD_Acquisition *acq) {
+ ismrmrd_init_acquisition_header(&(acq->head));
+ acq->traj = NULL;
+ acq->data = NULL;
+}
+
+void ismrmrd_copy_acquisition(ISMRMRD_Acquisition *acqdest, const ISMRMRD_Acquisition *acqsource) {
+ memcpy(&(acqdest->head), &(acqsource->head), sizeof(ISMRMRD_AcquisitionHeader));
+ ismrmrd_make_consistent_acquisition(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 ismrmrd_free_acquisition(ISMRMRD_Acquisition *acq) {
+ free(acq->data);
+ free(acq->traj);
+ free(acq);
+}
+
+void ismrmrd_make_consistent_acquisition(ISMRMRD_Acquisition *acq) {
+ if (acq->head.available_channels < acq->head.active_channels) {
+ acq->head.available_channels = acq->head.active_channels;
}
- /***************/
- /* Acquisition */
- /***************/
- void InitAcquisition(Acquisition* acq) {
- InitAcquisitionHeader(&(acq->head));
- acq->traj = NULL;
- acq->data = NULL;
+ 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));
}
- 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));
+ 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));
}
-
- void FreeAcquisition(Acquisition* acq) {
- free(acq->data);
- free(acq->traj);
- free(acq);
+}
+
+void ismrmrd_init_image_header(ISMRMRD_ImageHeader *hdr) {
+ memset(hdr, 0, sizeof(ISMRMRD_ImageHeader));
+ hdr->version = ISMRMRD_VERSION;
+ hdr->matrix_size[0] = 0;
+ hdr->matrix_size[1] = 1;
+ hdr->matrix_size[2] = 1;
+ hdr->channels = 1;
+}
+
+void ismrmrd_init_image(ISMRMRD_Image *im) {
+ ismrmrd_init_image_header(&(im->head));
+ im->attribute_string = NULL;
+ im->data = NULL;
+}
+
+void ismrmrd_free_image(ISMRMRD_Image *im) {
+ free(im->data);
+ free(im->attribute_string);
+ free(im);
+}
+
+int ismrmrd_size_of_image_data(const ISMRMRD_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 ISMRMRD_USHORT:
+ data_size = num_data * sizeof(uint16_t);
+ break;
+ case ISMRMRD_SHORT:
+ data_size = num_data * sizeof(int16_t);
+ break;
+ case ISMRMRD_UINT:
+ data_size = num_data * sizeof(uint32_t);
+ break;
+ case ISMRMRD_INT:
+ data_size = num_data * sizeof(int32_t);
+ break;
+ case ISMRMRD_FLOAT:
+ data_size = num_data * sizeof(float);
+ break;
+ case ISMRMRD_DOUBLE:
+ data_size = num_data * sizeof(double);
+ break;
+ case ISMRMRD_CXFLOAT:
+ data_size = num_data * sizeof(complex_float_t);
+ break;
+ case ISMRMRD_CXDOUBLE:
+ data_size = num_data * sizeof(complex_double_t);
+ break;
+ }
}
+ return data_size;
+}
- 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));
- }
+int ismrmrd_size_of_image_attribute_string(const ISMRMRD_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;
+}
- /****************/
- /* 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;
+void ismrmrd_make_consistent_image(ISMRMRD_Image *im) {
+ int attr_size = ismrmrd_size_of_image_attribute_string(im);
+ if (attr_size > 0) {
+ im->attribute_string = (char *)realloc(im->attribute_string, attr_size);
}
-
-
- /*********/
- /* Image */
- /*********/
- void InitImage(Image* im) {
- InitImageHeader(&(im->head));
- im->attribute_string = NULL;
- im->data = NULL;
+ int data_size = ismrmrd_size_of_image_data(im);
+ if (data_size > 0) {
+ im->data = realloc(im->data, data_size);
}
-
- void FreeImage(Image* im) {
- free(im->data);
- free(im->attribute_string);
- free(im);
+}
+
+void ismrmrd_copy_image(ISMRMRD_Image *imdest, const ISMRMRD_Image *imsource) {
+ memcpy(&(imdest->head), &(imsource->head), sizeof(ISMRMRD_ImageHeader));
+ ismrmrd_make_consistent_image(imdest);
+ int attr_size = ismrmrd_size_of_image_attribute_string(imdest);
+ if (attr_size > 0) {
+ memcpy(&(imdest->attribute_string), &(imsource->attribute_string), attr_size);
}
-
- 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 data_size = ismrmrd_size_of_image_data(imdest);
+ if (data_size > 0) {
+ memcpy(&(imdest->data), &(imsource->data), 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 ismrmrd_init_ndarray(ISMRMRD_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;
}
-
- 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);
- }
+ arr->data = NULL;
+}
+
+void ismrmrd_free_ndarray(ISMRMRD_NDArray *arr) {
+ free(arr->data);
+ free(arr);
+}
+
+int ismrmrd_size_of_ndarray_data(const ISMRMRD_NDArray *arr) {
+ int data_size = 0;
+ int num_data = 1;
+ for (int n = 0; n < ISMRMRD_NDARRAY_MAXDIM; n++) {
+ num_data *= arr->dims[n];
}
-
- 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);
- }
+ if (num_data > 0) {
+ switch (arr->data_type) {
+ case ISMRMRD_USHORT:
+ data_size = num_data * sizeof(uint16_t);
+ break;
+ case ISMRMRD_SHORT:
+ data_size = num_data * sizeof(int16_t);
+ break;
+ case ISMRMRD_UINT:
+ data_size = num_data * sizeof(uint32_t);
+ break;
+ case ISMRMRD_INT:
+ data_size = num_data * sizeof(int32_t);
+ break;
+ case ISMRMRD_FLOAT:
+ data_size = num_data * sizeof(float);
+ break;
+ case ISMRMRD_DOUBLE:
+ data_size = num_data * sizeof(double);
+ break;
+ case ISMRMRD_CXFLOAT:
+ data_size = num_data * sizeof(complex_float_t);
+ break;
+ case ISMRMRD_CXDOUBLE:
+ data_size = num_data * sizeof(complex_double_t);
+ break;
+ }
}
+ return 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 ismrmrd_make_consistent_ndarray(ISMRMRD_NDArray *arr) {
+ int data_size = ismrmrd_size_of_ndarray_data(arr);
+ if (data_size > 0) {
+ arr->data = realloc(arr->data, data_size);
}
-
- void FreeNDArray(NDArray* arr) {
- free(arr->data);
- free(arr);
+}
+
+void ismrmrd_copy_ndarray(ISMRMRD_NDArray *arrdest, const ISMRMRD_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];
}
-
- 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;
+ ismrmrd_make_consistent_ndarray(arrdest);
+ int data_size = ismrmrd_size_of_ndarray_data(arrdest);
+ if (data_size > 0) {
+ memcpy(&(arrdest->data), &(arrsource->data), ismrmrd_size_of_ndarray_data(arrdest));
}
-
- void MakeConsistentNDArray(NDArray* arr) {
- int data_size = SizeOfNDArrayData(arr);
- if (data_size > 0) {
- arr->data = realloc(arr->data, data_size);
- }
+}
+
+bool ismrmrd_is_flag_set(const uint64_t flags, const uint64_t val) {
+ uint64_t bitmask = 1;
+ bitmask = (bitmask << (val - 1));
+ return ((flags & bitmask) > 0);
+}
+
+void ismrmrd_set_flag(uint64_t *flags, const uint64_t val) {
+ uint64_t bitmask = 1;
+ bitmask = (bitmask << (val - 1));
+ *flags |= bitmask;
+}
+
+void ismrmrd_clear_flag(uint64_t *flags, const uint64_t val) {
+ uint64_t bitmask = 1;
+ bitmask = (bitmask << (val - 1));
+ if (ismrmrd_is_flag_set(*flags, val)) {
+ *flags &= ~bitmask;
+ };
+}
+
+void ismrmrd_clear_all_flags(uint64_t *flags) {
+ *flags = 0;
+}
+
+int ismrmrd_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;
}
-
- 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));
- }
+}
+
+void ismrmrd_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 (ismrmrd_sign_of_directions(read_dir, phase_dir, slice_dir) < 0) {
+ /* flip 3rd column */
+ r13 = -r13;
+ r23 = -r23;
+ r33 = -r33;
}
-
- /******************************/
- /* 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;
+ /* 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;
+ }
}
- 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;
- };
- }
+ quat[0] = (float)a;
+ quat[1] = (float)b;
+ quat[2] = (float)c;
+ quat[3] = (float)d;
+}
- void flags_clear_all(uint64_t* flags) {
- *flags = 0;
- }
+void ismrmrd_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];
- /******************************/
- /* 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;
- }
- }
+ 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);
- /**
- * 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;
- }
+ 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);
- /**
- * 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 );
- }
+ 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.cpp b/ismrmrd.cpp
new file mode 100644
index 0000000..5473d4b
--- /dev/null
+++ b/ismrmrd.cpp
@@ -0,0 +1,69 @@
+#include "ismrmrd.hpp"
+
+namespace ISMRMRD {
+
+AcquisitionHeader::AcquisitionHeader() {
+ ismrmrd_init_acquisition_header(this);
+};
+
+bool AcquisitionHeader::isFlagSet(const uint64_t val) {
+ return ismrmrd_is_flag_set(this->flags, val);
+};
+
+void AcquisitionHeader::setFlag(const uint64_t val) {
+ ismrmrd_set_flag(&(this->flags), val);
+};
+
+void AcquisitionHeader::clearFlag(const uint64_t val) {
+ ismrmrd_clear_flag(&(this->flags), val);
+};
+
+void AcquisitionHeader::clearAllFlags() {
+ ismrmrd_clear_all_flags(&(this->flags));
+};
+
+Acquisition::Acquisition() {
+ ismrmrd_init_acquisition(this);
+};
+
+const uint16_t &Acquisition::version() {
+ return (this->head.version);
+};
+uint64_t &Acquisition::flags() {
+ return (this->head.flags);
+};
+
+bool Acquisition::isFlagSet(const uint64_t val) {
+ return ismrmrd_is_flag_set((this->head.flags), val);
+};
+void Acquisition::setFlag(const uint64_t val) {
+ ismrmrd_set_flag(&(this->head.flags), val);
+};
+void Acquisition::clearFlag(const uint64_t val) {
+ ismrmrd_clear_flag(&(this->head.flags), val);
+};
+void Acquisition::clearAllFlags() {
+ ismrmrd_clear_all_flags(&(this->head.flags));
+};
+
+ImageHeader::ImageHeader() {
+ ismrmrd_init_image_header(this);
+};
+
+bool ImageHeader::isFlagSet(const uint64_t val) {
+ return ismrmrd_is_flag_set(this->flags, val);
+};
+
+void ImageHeader::setFlag(const uint64_t val) {
+ ismrmrd_set_flag(&(this->flags), val);
+};
+
+void ImageHeader::clearFlag(const uint64_t val) {
+ ismrmrd_clear_flag(&(this->flags), val);
+};
+
+void ImageHeader::clearAllFlags() {
+ ismrmrd_clear_all_flags(&(this->flags));
+};
+
+} // namespace ISMRMRD
diff --git a/ismrmrd.h b/ismrmrd.h
index 608dfa9..33be490 100644
--- a/ismrmrd.h
+++ b/ismrmrd.h
@@ -17,7 +17,7 @@
#ifdef __cplusplus
#ifdef _MSC_VER
-// MS C++ Compiler
+/* MS C++ Compiler */
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
@@ -26,7 +26,7 @@ typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
-// non MS C++ compiler
+/* non MS C++ compiler */
#include <cstdint>
#endif
@@ -38,7 +38,7 @@ typedef std::complex<float> complex_float_t;
typedef std::complex<double> complex_double_t;
#else
-// C99 compiler
+/* C99 compiler */
#include <stdint.h>
#include <complex.h>
#include <math.h>
@@ -48,284 +48,275 @@ typedef std::complex<double> complex_double_t;
typedef float complex complex_float_t;
typedef double complex complex_double_t;
-#endif // __cplusplus
+#endif /* __cplusplus */
-#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
+#pragma pack(push, 2) /* Use 2 byte alignment */
#ifdef __cplusplus
-namespace ISMRMRD {
-#endif //__cplusplus
+extern "C" {
+#endif
-/**************/
-/* 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
+/**
+ * Constants
+ *
+ */
+enum Constants {
+ ISMRMRD_VERSION = 1,
+ ISMRMRD_POSITION_LENGTH = 3,
+ ISMRMRD_DIRECTION_LENGTH = 3,
+ ISMRMRD_USER_INTS = 8,
+ ISMRMRD_USER_FLOATS = 8,
+ ISMRMRD_PHYS_STAMPS = 3,
+ ISMRMRD_CHANNEL_MASKS = 16,
+ ISMRMRD_NDARRAY_MAXDIM = 7
};
-/****************/
-/* Acquisitions */
-/****************/
+/**
+ * Data Types
+ */
+enum DataTypes {
+ ISMRMRD_USHORT = 1, /**< corresponds to uint16_t */
+ ISMRMRD_SHORT, /**< corresponds to int16_t */
+ ISMRMRD_UINT, /**< corresponds to uint32_t */
+ ISMRMRD_INT, /**< corresponds to int32_t */
+ ISMRMRD_FLOAT, /**< corresponds to float */
+ ISMRMRD_DOUBLE, /**< corresponds to double */
+ ISMRMRD_CXFLOAT, /**< corresponds to complex float */
+ ISMRMRD_CXDOUBLE, /**< corresponds to complex double */
+};
-/** ACQUISITION FLAGS */
+/**
+ * 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
+ ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP1 = 1,
+ ISMRMRD_ACQ_LAST_IN_ENCODE_STEP1,
+ ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP2,
+ ISMRMRD_ACQ_LAST_IN_ENCODE_STEP2,
+ ISMRMRD_ACQ_FIRST_IN_AVERAGE,
+ ISMRMRD_ACQ_LAST_IN_AVERAGE,
+ ISMRMRD_ACQ_FIRST_IN_SLICE,
+ ISMRMRD_ACQ_LAST_IN_SLICE,
+ ISMRMRD_ACQ_FIRST_IN_CONTRAST,
+ ISMRMRD_ACQ_LAST_IN_CONTRAST,
+ ISMRMRD_ACQ_FIRST_IN_PHASE,
+ ISMRMRD_ACQ_LAST_IN_PHASE,
+ ISMRMRD_ACQ_FIRST_IN_REPETITION,
+ ISMRMRD_ACQ_LAST_IN_REPETITION,
+ ISMRMRD_ACQ_FIRST_IN_SET,
+ ISMRMRD_ACQ_LAST_IN_SET,
+ ISMRMRD_ACQ_FIRST_IN_SEGMENT,
+ ISMRMRD_ACQ_LAST_IN_SEGMENT,
+ ISMRMRD_ACQ_IS_NOISE_MEASUREMENT,
+ ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION,
+ ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING,
+ ISMRMRD_ACQ_IS_REVERSE,
+ ISMRMRD_ACQ_IS_NAVIGATION_DATA,
+ ISMRMRD_ACQ_IS_PHASECORR_DATA,
+ ISMRMRD_ACQ_LAST_IN_MEASUREMENT,
+ ISMRMRD_ACQ_IS_HPFEEDBACK_DATA,
+ ISMRMRD_ACQ_IS_DUMMYSCAN_DATA,
+ ISMRMRD_ACQ_IS_RTFEEDBACK_DATA,
+ ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA,
+ ISMRMRD_ACQ_USER1 = 57,
+ ISMRMRD_ACQ_USER2,
+ ISMRMRD_ACQ_USER3,
+ ISMRMRD_ACQ_USER4,
+ ISMRMRD_ACQ_USER5,
+ ISMRMRD_ACQ_USER6,
+ ISMRMRD_ACQ_USER7,
+ ISMRMRD_ACQ_USER8
};
/**
- 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 */
-} EncodingCounters;
+ * Image Types
+ */
+enum ImageType {
+ ISMRMRD_IMTYPE_MAGNITUDE = 1,
+ ISMRMRD_IMTYPE_PHASE,
+ ISMRMRD_IMTYPE_REAL,
+ ISMRMRD_IMTYPE_IMAG,
+ ISMRMRD_IMTYPE_COMPLEX
+};
+
+/**
+ * Image Flags
+ */
+enum ImageFlags {
+ ISMRMRD_IMAGE_IS_NAVIGATION_DATA = 1,
+ ISMRMRD_IMAGE_USER1 = 57,
+ ISMRMRD_IMAGE_USER2,
+ ISMRMRD_IMAGE_USER3,
+ ISMRMRD_IMAGE_USER4,
+ ISMRMRD_IMAGE_USER5,
+ ISMRMRD_IMAGE_USER6,
+ ISMRMRD_IMAGE_USER7,
+ ISMRMRD_IMAGE_USER8
+};
+
+/**
+ * Struct used for keeping track of typical loop counters in MR experiment.
+ */
+typedef struct ISMRMRD_EncodingCounters {
+ uint16_t kspace_encode_step_1; /**< e.g. phase encoding line number */
+ uint16_t kspace_encode_step_2; /**< e.g. partition encoding 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 encoding set */
+ uint16_t segment; /**< e.g. segment number for segmented acquisition */
+ uint16_t user[ISMRMRD_USER_INTS]; /**< Free user parameters */
+} ISMRMRD_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 */
-} AcquisitionHeader;
+typedef struct ISMRMRD_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 */
+ ISMRMRD_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 */
+} ISMRMRD_AcquisitionHeader;
/* Initialize an Acquisition Header */
-void InitAcquisitionHeader(AcquisitionHeader* hdr);
+void ismrmrd_init_acquisition_header(ISMRMRD_AcquisitionHeader *hdr);
/**
Individual MR acquisition.
*/
-typedef struct Acquisition {
- AcquisitionHeader head; /**< Header, see above */
- float* traj;
- complex_float_t* data;
-} Acquisition;
+typedef struct ISMRMRD_Acquisition {
+ ISMRMRD_AcquisitionHeader head; /**< Header, see above */
+ float *traj;
+ complex_float_t *data;
+} ISMRMRD_Acquisition;
-void InitAcquisition(Acquisition* acq);
-void CopyAcquisition(Acquisition* acqdest, const Acquisition* acqsource);
-void FreeAcquisition(Acquisition* acq);
-void MakeConsistentAcquisition(Acquisition* acq);
+void ismrmrd_init_acquisition(ISMRMRD_Acquisition *acq);
+void ismrmrd_copy_acquisition(ISMRMRD_Acquisition *acqdest, const ISMRMRD_Acquisition *acqsource);
+void ismrmrd_free_acquisition(ISMRMRD_Acquisition *acq);
+void ismrmrd_make_consistent_acquisition(ISMRMRD_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
-};
-
/**
* Header for each Image
*/
-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;
-
-void InitImageHeader(ImageHeader* hdr);
+typedef struct ISMRMRD_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, breathing, 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 */
+} ISMRMRD_ImageHeader;
+
+void ismrmrd_init_image_header(ISMRMRD_ImageHeader *hdr);
/**
* An individual Image
*/
-typedef struct Image {
- ImageHeader head;
- void* data;
- char* attribute_string;
-} Image;
-
-void InitImage(Image* im);
-void FreeImage(Image* im);
-void MakeConsistentImage(Image* im);
+typedef struct ISMRMRD_Image {
+ ISMRMRD_ImageHeader head;
+ char *attribute_string;
+ void *data;
+} ISMRMRD_Image;
+
+void ismrmrd_init_image(ISMRMRD_Image *im);
+void ismrmrd_copy_image(ISMRMRD_Image *imdest, const ISMRMRD_Image *imsource);
+void ismrmrd_free_image(ISMRMRD_Image *im);
+void ismrmrd_make_consistent_image(ISMRMRD_Image *im);
+int ismrmrd_size_of_image_attribute_string(const ISMRMRD_Image *im);
+int ismrmrd_size_of_image_data(const ISMRMRD_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;
+typedef struct ISMRMRD_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 */
+} ISMRMRD_NDArray;
-void InitNDArray(NDArray* arr);
-void FreeNDArray(NDArray* arr);
-void MakeConsistentNDArray(NDArray* arr);
+void ismrmrd_init_ndarray(ISMRMRD_NDArray *arr);
+void ismrmrd_copy_ndarray(ISMRMRD_NDArray *arrdest, const ISMRMRD_NDArray *arrsource);
+void ismrmrd_free_ndarray(ISMRMRD_NDArray *arr);
+void ismrmrd_make_consistent_ndarray(ISMRMRD_NDArray *arr);
+int ismrmrd_size_of_ndarray_data(const ISMRMRD_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);
+bool ismrmrd_is_flag_set(const uint64_t flags, const uint64_t val);
+void ismrmrd_set_flag(uint64_t *flags, const uint64_t val);
+void ismrmrd_clear_flag(uint64_t *flags, const uint64_t val);
+void ismrmrd_clear_all_flags(uint64_t *flags);
/*****************************/
/* Rotations and Quaternions */
/*****************************/
/* 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]);
+int ismrmrd_sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3]);
/* 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]);
+void ismrmrd_directions_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
+ *
+ * http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html#Q54
+ */
+void ismrmrd_quaternion_to_directions(float quat[4], float read_dir[3], float phase_dir[3], float slice_dir[3]);
-/* Converts a quaternion of the form | a b c d | to a 3x3 rotation matrix */
-void quaternion_to_directions(float quat[4], float read_dir[3],
- float phase_dir[3], float slice_dir[3]);
+#pragma pack(pop) // Restore old alignment
#ifdef __cplusplus
-} // End of ISMRMRD namespace
-#endif //__cplusplus
-
-#pragma pack(pop) // Restore old alignment
+} //End of extern C
+#endif
-#endif // ISMRMRD_H
+#endif // ISMRMRD_H
diff --git a/ismrmrd.hpp b/ismrmrd.hpp
new file mode 100644
index 0000000..2e7de5d
--- /dev/null
+++ b/ismrmrd.hpp
@@ -0,0 +1,59 @@
+//
+// ISMRMRD C++ Interface
+//
+
+#include "ismrmrd.h"
+
+#pragma once
+#ifndef ISMRMRD_HPP
+#define ISMRMRD_HPP
+
+namespace ISMRMRD {
+
+class AcquisitionHeader : protected ISMRMRD_AcquisitionHeader {
+public:
+ explicit AcquisitionHeader();
+
+ // Accessors and mutators
+ const uint16_t &version();
+ uint64_t &flags();
+
+ // Flag methods
+ bool isFlagSet(const uint64_t val);
+ void setFlag(const uint64_t val);
+ void clearFlag(const uint64_t val);
+ void clearAllFlags();
+};
+
+class Acquisition : protected ISMRMRD_Acquisition {
+public:
+ explicit Acquisition();
+
+ // Accessors and mutators
+ const uint16_t &version();
+ uint64_t &flags();
+
+ // Flag methods
+ bool isFlagSet(const uint64_t val);
+ void setFlag(const uint64_t val);
+ void clearFlag(const uint64_t val);
+ void clearAllFlags();
+};
+
+class ImageHeader : protected ISMRMRD_ImageHeader {
+ explicit ImageHeader();
+ bool isFlagSet(const uint64_t val);
+ void setFlag(const uint64_t val);
+ void clearFlag(const uint64_t val);
+ void clearAllFlags();
+};
+
+class Image : protected ISMRMRD_Image {
+};
+
+class NDArray : protected ISMRMRD_NDArray {
+};
+
+} // namespace ISMRMRD
+
+#endif // ISMRMRD_HPP
diff --git a/tests/c++/basic_test.cpp b/tests/c++/basic_test.cpp
new file mode 100644
index 0000000..3b46f4b
--- /dev/null
+++ b/tests/c++/basic_test.cpp
@@ -0,0 +1,35 @@
+#include <iostream>
+#include "ismrmrd.hpp"
+
+int main (int args, char** argv) {
+
+ using namespace ISMRMRD;
+
+ AcquisitionHeader acqhdr;
+ std::cout << "Version: " << acqhdr.version << std::endl;
+ std::cout << "Flags 0: " << acqhdr.flags << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acqhdr.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+ acqhdr.setFlag(ISMRMRD_ACQ_FIRST_IN_SLICE);
+ std::cout << "Flags 1: " << acqhdr.flags << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acqhdr.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+ acqhdr.clearFlag(ISMRMRD_ACQ_FIRST_IN_SLICE);
+ std::cout << "Flags 2: " << acqhdr.flags << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acqhdr.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+
+ Acquisition acq;
+ std::cout << "Version: " << acq.version() << std::endl;
+ std::cout << "Flags 0: " << acq.flags() << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acq.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+ acq.setFlag(ISMRMRD_ACQ_FIRST_IN_SLICE);
+ std::cout << "Flags 1: " << acq.flags() << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acq.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+ acq.clearFlag(ISMRMRD_ACQ_FIRST_IN_SLICE);
+ std::cout << "Flags 2: " << acq.flags() << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acq.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+ acq.flags() = 64;
+ std::cout << "Flags 3: " << acq.flags() << std::endl;
+ std::cout << "ACQ_FIRST_IN_SLICE: " << acq.isFlagSet(ISMRMRD_ACQ_FIRST_IN_SLICE) << std::endl;
+
+
+ return 0;
+}
diff --git a/tests/c/basic_test.c b/tests/c/basic_test.c
index e1398b5..7f7bd3e 100644
--- a/tests/c/basic_test.c
+++ b/tests/c/basic_test.c
@@ -1,36 +1,32 @@
#include <stdio.h>
#include <ismrmrd.h>
-#ifdef __cplusplus
-using namespace ISMRMRD;
-#endif
-
int main(void)
{
- Acquisition acq;
- InitAcquisition(&acq);
+ ISMRMRD_Acquisition acq;
+ ismrmrd_init_acquisition(&acq);
acq.head.number_of_samples = 128;
acq.head.active_channels = 4;
- MakeConsistentAcquisition(&acq);
+ ismrmrd_make_consistent_acquisition(&acq);
printf("Acq Version: %d\n", acq.head.version);
- flags_set(&(acq.head.flags), ACQ_FIRST_IN_SLICE);
+ ismrmrd_set_flag(&(acq.head.flags), ISMRMRD_ACQ_FIRST_IN_SLICE);
printf("Flags: %llu\n", acq.head.flags);
- printf("ACQ_FIRST_IN_SLICE: %d\n", flags_is_set(acq.head.flags, ACQ_FIRST_IN_SLICE));
- flags_clear(&(acq.head.flags), ACQ_FIRST_IN_SLICE);
+ printf("ACQ_FIRST_IN_SLICE: %d\n", ismrmrd_is_flag_set(acq.head.flags, ISMRMRD_ACQ_FIRST_IN_SLICE));
+ ismrmrd_clear_flag(&(acq.head.flags), ISMRMRD_ACQ_FIRST_IN_SLICE);
printf("Flags: %llu\n", acq.head.flags);
- printf("ACQ_FIRST_IN_SLICE: %d\n", flags_is_set(acq.head.flags, ACQ_FIRST_IN_SLICE));
+ printf("ACQ_FIRST_IN_SLICE: %d\n", ismrmrd_is_flag_set(acq.head.flags, ISMRMRD_ACQ_FIRST_IN_SLICE));
- Image im;
- InitImage(&im);
- printf("Image Version: %d\n", im.head.version);
+ // Image im;
+ //initImage(&im);
+ //printf("Image Version: %d\n", im.head.version);
- NDArray arr;
- InitNDArray(&arr);
- printf("Array ndim: %d\n", arr.ndim);
- printf("Array dim[0]: %d\n", arr.dims[0]);
+ //NDArray arr;
+ //initNDArray(&arr);
+ //printf("Array ndim: %d\n", arr.ndim);
+ //printf("Array dim[0]: %d\n", arr.dims[0]);
return 0;
}
--
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