RNifti: inst/include/RNifti/NiftiImage.h Source File

RNifti Fast R and C++ Access to NIfTI Images

NiftiImage.h
1 #ifndef _NIFTI_IMAGE_H_
2 #define _NIFTI_IMAGE_H_
3
4
5 #ifdef USING_R
6
7 #include <Rcpp.h>
8
9 // Defined since R 3.1.0, according to Tomas Kalibera, but there's no reason to break
10 // compatibility with 3.0.x
11 #ifndef MAYBE_SHARED
12 #define MAYBE_SHARED(x) (NAMED(x) > 1)
13 #endif
14
15 #else
16
17 #define R_NegInf -INFINITY
18
19 #include <stdint.h>
20 #include <cstddef>
21 #include <cmath>
22 #include <string>
23 #include <sstream>
24 #include <vector>
25 #include <complex>
26 #include <stdexcept>
27 #include <algorithm>
28 #include <map>
29 #include <locale>
30 #include <limits>
31
32 #endif
33
42 namespace RNifti {
43
44 typedef std::complex<float> complex64_t;
45 typedef std::complex<double> complex128_t;
46
53 struct rgba32_t
54 {
55 union ValueType {
56 int packed;
57 unsigned char bytes[4];
58 };
59 ValueType value;
60 rgba32_t () { value.packed = 0; }
61 };
62
70 class NiftiImageData
71 {
72 public:
73 double slope;
74 double intercept;
76 protected:
80 struct TypeHandler
81 {
82 virtual ~TypeHandler() {}
83 virtual size_t size () const { return 0; }
84 virtual bool hasNaN () const { return false; }
85 virtual complex128_t getComplex (void *ptr) const { return complex128_t(0.0, 0.0); }
86 virtual double getDouble (void *ptr) const { return 0.0; }
87 virtual int getInt (void *ptr) const { return 0; }
88 virtual rgba32_t getRgb (void *ptr) const { return rgba32_t(); }
89 virtual void setComplex (void *ptr, const complex128_t value) const {}
90 virtual void setDouble (void *ptr, const double value) const {}
91 virtual void setInt (void *ptr, const int value) const {}
92 virtual void setRgb (void *ptr, const rgba32_t value) const {}
93 virtual void minmax (void *ptr, const size_t length, double *min, double *max) const { *min = 0.0; *max = 0.0; }
94 };
95
99 template <typename Type, bool alpha = false>
100 struct ConcreteTypeHandler : public TypeHandler
101 {
102 size_t size () const { return (sizeof(Type)); }
103 bool hasNaN () const { return std::numeric_limits<Type>::has_quiet_NaN; }
104 complex128_t getComplex (void *ptr) const { return complex128_t(static_cast<double>(*static_cast<Type*>(ptr)), 0.0); }
105 double getDouble (void *ptr) const { return static_cast<double>(*static_cast<Type*>(ptr)); }
106 int getInt (void *ptr) const { return static_cast<int>(*static_cast<Type*>(ptr)); }
107 void setComplex (void *ptr, const complex128_t value) const
108 {
109 *(static_cast<Type*>(ptr)) = Type(value.real());
110 *(static_cast<Type*>(ptr) + 1) = Type(0);
111 }
112 void setDouble (void *ptr, const double value) const { *(static_cast<Type*>(ptr)) = Type(value); }
113 void setInt (void *ptr, const int value) const { *(static_cast<Type*>(ptr)) = Type(value); }
114 void minmax (void *ptr, const size_t length, double *min, double *max) const;
115 };
116
117 template <typename ElementType>
118 struct ConcreteTypeHandler<std::complex<ElementType>,false> : public TypeHandler
119 {
120 size_t size () const { return (sizeof(ElementType) * 2); }
121 bool hasNaN () const { return std::numeric_limits<ElementType>::has_quiet_NaN; }
122 std::complex<ElementType> getNative (void *ptr) const
123 {
124 const ElementType real = *static_cast<ElementType*>(ptr);
125 const ElementType imag = *(static_cast<ElementType*>(ptr) + 1);
126 return std::complex<ElementType>(real, imag);
127 }
128 void setNative (void *ptr, const std::complex<ElementType> native) const
129 {
130 *(static_cast<ElementType*>(ptr)) = native.real();
131 *(static_cast<ElementType*>(ptr) + 1) = native.imag();
132 }
133 complex128_t getComplex (void *ptr) const { return complex128_t(getNative(ptr)); }
134 double getDouble (void *ptr) const { return static_cast<double>(getNative(ptr).real()); }
135 int getInt (void *ptr) const { return static_cast<int>(getNative(ptr).real()); }
136 void setComplex (void *ptr, const complex128_t value) const { setNative(ptr, std::complex<ElementType>(value)); }
137 void setDouble (void *ptr, const double value) const { setNative(ptr, std::complex<ElementType>(value, 0.0)); }
138 void setInt (void *ptr, const int value) const { setNative(ptr, std::complex<ElementType>(static_cast<ElementType>(value), 0.0)); }
139 void minmax (void *ptr, const size_t length, double *min, double *max) const;
140 };
141
142 template <bool alpha>
143 struct ConcreteTypeHandler<rgba32_t,alpha> : public TypeHandler
144 {
145 size_t size () const { return alpha ? 4 : 3; }
146 int getInt (void *ptr) const { return getRgb(ptr).value.packed; }
147 rgba32_t getRgb (void *ptr) const
148 {
149 rgba32_t value;
150 unsigned char *source = static_cast<unsigned char *>(ptr);
151 std::copy(source, source + (alpha ? 4 : 3), value.value.bytes);
152 return value;
153 }
154 void setInt (void *ptr, const int value) const
155 {
156 rgba32_t native;
157 native.value.packed = value;
158 setRgb(ptr, native);
159 }
160 void setRgb (void *ptr, const rgba32_t value) const
161 {
162 unsigned char *target = static_cast<unsigned char *>(ptr);
163 std::copy(value.value.bytes, value.value.bytes + (alpha ? 4 : 3), target);
164 }
165 void minmax (void *ptr, const size_t length, double *min, double *max) const { *min = 0.0; *max = 255.0; }
166 };
167
173 TypeHandler * createHandler ()
174 {
175 if (_datatype == DT_NONE)
176 return NULL;
177
178 switch (_datatype)
179 {
180 case DT_UINT8: return new ConcreteTypeHandler<uint8_t>(); break;
181 case DT_INT16: return new ConcreteTypeHandler<int16_t>(); break;
182 case DT_INT32: return new ConcreteTypeHandler<int32_t>(); break;
183 case DT_FLOAT32: return new ConcreteTypeHandler<float>(); break;
184 case DT_FLOAT64: return new ConcreteTypeHandler<double>(); break;
185 case DT_INT8: return new ConcreteTypeHandler<int8_t>(); break;
186 case DT_UINT16: return new ConcreteTypeHandler<uint16_t>(); break;
187 case DT_UINT32: return new ConcreteTypeHandler<uint32_t>(); break;
188 case DT_INT64: return new ConcreteTypeHandler<int64_t>(); break;
189 case DT_UINT64: return new ConcreteTypeHandler<uint64_t>(); break;
190 case DT_COMPLEX64: return new ConcreteTypeHandler<complex64_t>(); break;
191 case DT_COMPLEX128: return new ConcreteTypeHandler<complex128_t>(); break;
192 case DT_RGB24: return new ConcreteTypeHandler<rgba32_t,false>(); break;
193 case DT_RGBA32: return new ConcreteTypeHandler<rgba32_t,true>(); break;
194
195 default:
196 throw std::runtime_error("Unsupported data type (" + std::string(nifti_datatype_string(_datatype)) + ")");
197 }
198 }
199
200 void *dataPtr;
201 int _datatype;
202 TypeHandler *handler;
203 size_t _length;
204 bool owner;
216 void init (void *data, const size_t length, const int datatype, const double slope, const double intercept, const bool alloc = true)
217 {
218 this->_length = length;
219 this->_datatype = datatype;
220 this->slope = slope;
221 this->intercept = intercept;
222
223 owner = false;
224 handler = createHandler();
225 if (handler == NULL)
226 dataPtr = NULL;
227 else if (alloc && data == NULL)
228 {
229 dataPtr = calloc(length, handler->size());
230 owner = true;
231 }
232 else
233 dataPtr = data;
234 }
235
242 void calibrateFrom (const NiftiImageData &data)
243 {
244 slope = 1.0;
245 intercept = 0.0;
246
247 if (this->isInteger())
248 {
249 double dataMin, dataMax, typeMin, typeMax;
250 data.minmax(&dataMin, &dataMax);
251 handler->minmax(NULL, 0, &typeMin, &typeMax);
252
253 // If the source type is floating-point but values are in range, we will just round them
254 if (dataMin < typeMin || dataMax > typeMax)
255 {
256 slope = (dataMax - dataMin) / (typeMax - typeMin);
257 intercept = dataMin - (slope) * typeMin;
258 }
259 }
260 }
261
262 public:
266 struct Element
267 {
268 private:
269 const NiftiImageData &parent;
270 void *ptr;
271
272 public:
279 Element (const NiftiImageData &parent, void *ptr = NULL)
280 : parent(parent)
281 {
282 this->ptr = (ptr == NULL ? parent.dataPtr : ptr);
283 }
284
292 template <typename SourceType>
293 Element & operator= (const SourceType &value);
294
300 Element & operator= (const Element &other);
301
305 template <typename TargetType>
306 operator TargetType() const
307 {
308 if (parent.isScaled())
309 return TargetType(parent.handler->getDouble(ptr) * parent.slope + parent.intercept);
310 else if (std::numeric_limits<TargetType>::is_integer)
311 return TargetType(parent.handler->getInt(ptr));
312 else
313 return TargetType(parent.handler->getDouble(ptr));
314 }
315
316 template <typename ElementType>
317 operator std::complex<ElementType>() const
318 {
319 if (parent.isScaled())
320 return std::complex<ElementType>(parent.handler->getComplex(ptr) * parent.slope + complex128_t(parent.intercept, parent.intercept));
321 else
322 return std::complex<ElementType>(parent.handler->getComplex(ptr));
323 }
324
325 #ifdef USING_R
326
329 operator Rcomplex() const
330 {
331 const complex128_t value = parent.handler->getComplex(ptr);
332 Rcomplex rValue = { value.real(), value.imag() };
333 if (parent.isScaled())
334 {
335 rValue.r = rValue.r * parent.slope + parent.intercept;
336 rValue.i = rValue.i * parent.slope + parent.intercept;
337 }
338 return rValue;
339 }
340 #endif
341
342 operator rgba32_t() const
343 {
344 return parent.handler->getRgb(ptr);
345 }
346 };
347
351 class Iterator : public std::iterator<std::random_access_iterator_tag, Element>
352 {
353 private:
354 const NiftiImageData &parent;
355 void *ptr;
356 size_t step;
357
358 public:
366 Iterator (const NiftiImageData &parent, void *ptr = NULL, const size_t step = 0)
367 : parent(parent)
368 {
369 this->ptr = (ptr == NULL ? parent.dataPtr : ptr);
370 this->step = (step == 0 ? parent.handler->size() : step);
371 }
372
377 Iterator (const Iterator &other)
378 : parent(other.parent), ptr(other.ptr), step(other.step) {}
379
380 Iterator & operator++ () { ptr = static_cast<char*>(ptr) + step; return *this; }
381 Iterator operator++ (int) { Iterator copy(*this); ptr = static_cast<char*>(ptr) + step; return copy; }
382 Iterator operator+ (ptrdiff_t n) const
383 {
384 void *newptr = static_cast<char*>(ptr) + (n * step);
385 return Iterator(parent, newptr, step);
386 }
387 Iterator & operator-- () { ptr = static_cast<char*>(ptr) - step; return *this; }
388 Iterator operator-- (int) { Iterator copy(*this); ptr = static_cast<char*>(ptr) - step; return copy; }
389 Iterator operator- (ptrdiff_t n) const
390 {
391 void *newptr = static_cast<char*>(ptr) - (n * step);
392 return Iterator(parent, newptr, step);
393 }
394
395 ptrdiff_t operator- (const Iterator &other) const
396 {
397 const ptrdiff_t difference = static_cast<char*>(ptr) - static_cast<char*>(other.ptr);
398 return difference / step;
399 }
400
401 bool operator== (const Iterator &other) const { return (ptr==other.ptr && step==other.step); }
402 bool operator!= (const Iterator &other) const { return (ptr!=other.ptr || step!=other.step); }
403 bool operator> (const Iterator &other) const { return (ptr > other.ptr); }
404 bool operator< (const Iterator &other) const { return (ptr < other.ptr); }
405
406 const Element operator* () const { return Element(parent, ptr); }
407 Element operator* () { return Element(parent, ptr); }
408 const Element operator[] (const size_t i) const { return Element(parent, static_cast<char*>(ptr) + (i * step)); }
409 Element operator[] (const size_t i) { return Element(parent, static_cast<char*>(ptr) + (i * step)); }
410 };
411
415 NiftiImageData ()
416 : slope(1.0), intercept(0.0), dataPtr(NULL), _datatype(DT_NONE), handler(NULL), _length(0), owner(false) {}
417
427 NiftiImageData (void *data, const size_t length, const int datatype, const double slope = 1.0, const double intercept = 0.0)
428 {
429 init(data, length, datatype, slope, intercept);
430 }
431
436 NiftiImageData (nifti_image *image)
437 {
438 if (image == NULL)
439 init(NULL, 0, DT_NONE, 0.0, 0.0, false);
440 else
441 init(image->data, image->nvox, image->datatype, static_cast<double>(image->scl_slope), static_cast<double>(image->scl_inter), false);
442 }
443
451 NiftiImageData (const NiftiImageData &source, const int datatype = DT_NONE)
452 {
453 init(NULL, source.length(), datatype == DT_NONE ? source.datatype() : datatype, source.slope, source.intercept);
454
455 if (datatype == DT_NONE || datatype == source.datatype())
456 memcpy(dataPtr, source.dataPtr, source.totalBytes());
457 else
458 {
459 calibrateFrom(source);
460 std::copy(source.begin(), source.end(), this->begin());
461 }
462 }
463
470 template <class InputIterator>
471 NiftiImageData (InputIterator from, InputIterator to, const int datatype)
472 {
473 const size_t length = static_cast<size_t>(std::distance(from, to));
474 init(NULL, length, datatype, 1.0, 0.0);
475 std::copy(from, to, this->begin());
476 }
477
481 virtual ~NiftiImageData ()
482 {
483 delete handler;
484 if (owner)
485 free(dataPtr);
486 }
487
493 NiftiImageData & operator= (const NiftiImageData &source)
494 {
495 if (source.dataPtr != NULL)
496 {
497 // Free the old data, if we allocated it
498 if (owner)
499 free(dataPtr);
500 init(NULL, source.length(), source.datatype(), source.slope, source.intercept);
501 memcpy(dataPtr, source.dataPtr, source.totalBytes());
502 }
503 return *this;
504 }
505
506 void * blob () const { return dataPtr; }
507 int datatype () const { return _datatype; }
508 size_t length () const { return _length; }
509 size_t size () const { return _length; }
512 size_t bytesPerPixel () const { return (handler == NULL ? 0 : handler->size()); }
513
515 size_t totalBytes () const { return _length * bytesPerPixel(); }
516
521 bool isEmpty () const { return (dataPtr == NULL); }
522
528 bool isScaled () const { return (slope != 0.0 && (slope != 1.0 || intercept != 0.0)); }
529
534 bool isComplex () const { return (_datatype == DT_COMPLEX64 || _datatype == DT_COMPLEX128); }
535
541 bool isFloatingPoint () const { return (_datatype == DT_FLOAT32 || _datatype == DT_FLOAT64); }
542
547 bool isInteger () const { return nifti_is_inttype(_datatype); }
548
553 bool isRgb () const { return (_datatype == DT_RGB24 || _datatype == DT_RGBA32); }
554
559 NiftiImageData unscaled () const { return NiftiImageData(dataPtr, _length, _datatype); }
560
565 NiftiImageData & disown () { this->owner = false; return *this; }
566
568 const Iterator begin () const { return Iterator(*this); }
569
571 const Iterator end () const { return Iterator(*this, static_cast<char*>(dataPtr) + totalBytes()); }
572
574 Iterator begin () { return Iterator(*this); }
575
577 Iterator end () { return Iterator(*this, static_cast<char*>(dataPtr) + totalBytes()); }
578
584 const Element operator[] (const size_t i) const { return Element(*this, static_cast<char*>(dataPtr) + (i * bytesPerPixel())); }
585
591 Element operator[] (const size_t i) { return Element(*this, static_cast<char*>(dataPtr) + (i * bytesPerPixel())); }
592
600 void minmax (double *min, double *max) const
601 {
602 if (handler == NULL)
603 {
604 *min = 0.0;
605 *max = 0.0;
606 }
607 else
608 handler->minmax(dataPtr, _length, min, max);
609 }
610 };
611
612
613 // R provides an NaN (NA) value for integers
614 #ifdef USING_R
615 template <>
616 inline bool NiftiImageData::ConcreteTypeHandler<int>::hasNaN () const { return true; }
617 #endif
618
619
620 template <typename ElementType, int Length>
621 class Vector
622 {
623 protected:
624 ElementType elements[Length];
625
626 public:
627 Vector (const ElementType value = 0.0)
628 {
629 std::fill(elements, elements + Length, value);
630 }
631
632 Vector (const ElementType * source)
633 {
634 std::copy(source, source + Length, this->elements);
635 }
636
637 Vector<ElementType,Length> operator- () const
638 {
639 Vector<ElementType,Length> result;
640 for (int i=0; i<Length; i++)
641 result.elements[i] = -elements[i];
642 return result;
643 }
644
645 const ElementType & operator[] (const size_t i) const { return elements[i]; }
646
647 ElementType & operator[] (const size_t i) { return elements[i]; }
648 };
649
650 template <class NiftiType, typename ElementType, int Order>
651 class SquareMatrix
652 {
653 protected:
654 ElementType elements[Order*Order];
655
656 NiftiType * niftiPointer () const { return (NiftiType *) elements; }
657 NiftiType niftiCopy () const
658 {
659 NiftiType value;
660 std::copy(elements, elements + Order*Order, *value.m);
661 return value;
662 }
663
664 public:
665 typedef NiftiType NativeType;
666 typedef SquareMatrix<NiftiType,ElementType,Order> MatrixType;
667 typedef Vector<ElementType,Order> VectorType;
668
669 SquareMatrix (const ElementType value = 0.0)
670 {
671 std::fill(elements, elements + Order*Order, value);
672 }
673
674 SquareMatrix (const ElementType * source)
675 {
676 std::copy(source, source + Order*Order, this->elements);
677 }
678
679 SquareMatrix (const NiftiType &source)
680 {
681 std::copy(*source.m, *source.m + Order*Order, this->elements);
682 }
683
684 operator const NiftiType () const { return niftiCopy(); }
685
686 operator NiftiType () { return niftiCopy(); }
687
688 const ElementType * begin () const { return elements; }
689
690 ElementType * begin () { return elements; }
691
692 const ElementType * end () const { return elements + Order*Order; }
693
694 ElementType * end () { return elements + Order*Order; }
695
696 static MatrixType eye ()
697 {
698 MatrixType matrix;
699 for (int i=0; i<Order; i++)
700 matrix.elements[i + i*Order] = 1.0;
701 return matrix;
702 }
703
704 MatrixType inverse () const;
705 MatrixType polar () const;
706 ElementType colnorm () const;
707 ElementType rownorm () const;
708 ElementType determ () const;
709 MatrixType multiply (const MatrixType &other) const;
710 VectorType multiply (const VectorType &vec) const;
711
712 MatrixType operator* (const MatrixType &other) const { return multiply(other); }
713 VectorType operator* (const VectorType &vec) const { return multiply(vec); }
714
715 const ElementType & operator() (const int i, const int j) const { return elements[j + i*Order]; }
716 ElementType & operator() (const int i, const int j) { return elements[j + i*Order]; }
717 };
718
719
720 // Include matrix implementations
721 #include "RNifti/NiftiImage_matrix.h"
722
723
730 class NiftiImage
731 {
732 public:
733 #if RNIFTI_NIFTILIB_VERSION == 1
734 typedef int dim_t;
735 typedef float pixdim_t;
736 typedef float scale_t;
737 #elif RNIFTI_NIFTILIB_VERSION == 2
738 typedef int64_t dim_t;
739 typedef double pixdim_t;
740 typedef double scale_t;
741 #endif
742
747 struct Block
748 {
749 const NiftiImage &image;
750 const int dimension;
751 const dim_t index;
760 Block (const NiftiImage &image, const int dimension, const dim_t index)
761 : image(image), dimension(dimension), index(index)
762 {
763 if (dimension != image->ndim)
764 throw std::runtime_error("Blocks must be along the last dimension in the image");
765 }
766
775 Block & operator= (const NiftiImage &source)
776 {
777 if (source->datatype != image->datatype)
778 throw std::runtime_error("New data does not have the same datatype as the target block");
779 if (source->scl_slope != image->scl_slope || source->scl_inter != image->scl_inter)
780 throw std::runtime_error("New data does not have the same scale parameters as the target block");
781
782 size_t blockSize = 1;
783 for (int i=1; i<dimension; i++)
784 blockSize *= image->dim[i];
785
786 if (blockSize != source->nvox)
787 throw std::runtime_error("New data does not have the same size as the target block");
788
789 blockSize *= image->nbyper;
790 memcpy(static_cast<char*>(image->data) + blockSize*index, source->data, blockSize);
791 return *this;
792 }
793
798 NiftiImageData data () const
799 {
800 if (image.isNull())
801 return NiftiImageData();
802 else
803 {
804 size_t blockSize = 1;
805 for (int i=1; i<dimension; i++)
806 blockSize *= image->dim[i];
807 return NiftiImageData(static_cast<char*>(image->data) + blockSize * index * image->nbyper, blockSize, image->datatype, static_cast<double>(image->scl_slope), static_cast<double>(image->scl_inter));
808 }
809 }
810
818 template <typename TargetType>
819 std::vector<TargetType> getData (const bool useSlope = true) const;
820 };
821
822 class Xform
823 {
824 public:
825 #if RNIFTI_NIFTILIB_VERSION == 1
826 typedef float Element;
827 typedef Vector<float,4> Vector4;
828 typedef Vector<float,3> Vector3;
829 typedef SquareMatrix<mat44,float,4> Matrix;
830 typedef SquareMatrix<mat33,float,3> Submatrix;
831 #elif RNIFTI_NIFTILIB_VERSION == 2
832 typedef double Element;
833 typedef Vector<double,4> Vector4;
834 typedef Vector<double,3> Vector3;
835 typedef SquareMatrix<nifti_dmat44,double,4> Matrix;
836 typedef SquareMatrix<nifti_dmat33,double,3> Submatrix;
837 #endif
838
839 protected:
840 Element *forward, *inverse, *qparams;
841 Matrix mat;
842
843 void replace (const Matrix &source);
844
845 public:
846 Xform ()
847 : forward(NULL), inverse(NULL), qparams(NULL), mat() {}
848
849 Xform (const Matrix &source)
850 : forward(NULL), inverse(NULL), qparams(NULL), mat(source) {}
851
852 Xform (const Matrix::NativeType &source)
853 : forward(NULL), inverse(NULL), qparams(NULL), mat(source) {}
854
855 Xform (Matrix::NativeType &source)
856 : forward(*source.m), inverse(NULL), qparams(NULL), mat(source) {}
857
858 Xform (Matrix::NativeType &source, Matrix::NativeType &inverse, Element *qparams = NULL)
859 : forward(*source.m), inverse(*inverse.m), qparams(qparams), mat(source) {}
860
861 operator const Matrix::NativeType () const { return mat; }
862
863 operator Matrix::NativeType () { return mat; }
864
865 Xform & operator= (const Xform &source)
866 {
867 replace(source.mat);
868 return *this;
869 }
870
871 Xform & operator= (const Matrix &source)
872 {
873 replace(source);
874 return *this;
875 }
876
877 const Matrix & matrix () const { return mat; }
878 Submatrix submatrix () const;
879 Submatrix rotation () const;
880 Vector4 quaternion () const;
881 Vector3 offset () const;
882 std::string orientation () const;
883 };
884
885 #ifdef USING_R
886
892 static int sexpTypeToNiftiType (const int sexpType)
893 {
894 if (sexpType == INTSXP || sexpType == LGLSXP)
895 return DT_INT32;
896 else if (sexpType == REALSXP)
897 return DT_FLOAT64;
898 else if (sexpType == CPLXSXP)
899 return DT_COMPLEX128;
900 else
901 throw std::runtime_error("Array elements must be numeric");
902 }
903 #endif
904
911 static int fileVersion (const std::string &path);
912
913
914 protected:
915 nifti_image *image;
916 int *refCount;
924 void acquire (nifti_image * const image);
925
930 void acquire (const NiftiImage &source)
931 {
932 refCount = source.refCount;
933 acquire(source.image);
934 }
935
940 void release ();
941
946 void copy (const nifti_image *source);
947
952 void copy (const NiftiImage &source);
953
958 void copy (const Block &source);
959
960
961 #ifdef USING_R
962
968 void initFromNiftiS4 (const Rcpp::RObject &object, const bool copyData = true);
969
975 void initFromMriImage (const Rcpp::RObject &object, const bool copyData = true);
976
981 void initFromList (const Rcpp::RObject &object);
982
988 void initFromArray (const Rcpp::RObject &object, const bool copyData = true);
989
990 #endif
991
997 void initFromDims (const std::vector<dim_t> &dim, const int datatype);
998
1003 void updatePixdim (const std::vector<pixdim_t> &pixdim);
1004
1009 void setPixunits (const std::vector<std::string> &pixunits);
1010
1011 public:
1015 NiftiImage ()
1016 : image(NULL), refCount(NULL) {}
1017
1024 NiftiImage (const NiftiImage &source, const bool copy = true)
1025 : image(NULL), refCount(NULL)
1026 {
1027 if (copy)
1028 this->copy(source);
1029 else
1030 acquire(source);
1031 #ifndef NDEBUG
1032 Rc_printf("Creating NiftiImage with pointer %p (from NiftiImage)\n", this->image);
1033 #endif
1034 }
1035
1040 NiftiImage (const Block &source)
1041 : image(NULL), refCount(NULL)
1042 {
1043 this->copy(source);
1044 #ifndef NDEBUG
1045 Rc_printf("Creating NiftiImage with pointer %p (from Block)\n", this->image);
1046 #endif
1047 }
1048
1055 NiftiImage (nifti_image * const image, const bool copy = false)
1056 : image(NULL), refCount(NULL)
1057 {
1058 if (copy)
1059 this->copy(image);
1060 else
1061 acquire(image);
1062 #ifndef NDEBUG
1063 Rc_printf("Creating NiftiImage with pointer %p (from pointer)\n", this->image);
1064 #endif
1065 }
1066
1072 NiftiImage (const std::vector<dim_t> &dim, const int datatype);
1073
1079 NiftiImage (const std::vector<dim_t> &dim, const std::string &datatype);
1080
1087 NiftiImage (const std::string &path, const bool readData = true);
1088
1095 NiftiImage (const std::string &path, const std::vector<dim_t> &volumes);
1096
1097 #ifdef USING_R
1098
1108 NiftiImage (const SEXP object, const bool readData = true, const bool readOnly = false);
1109 #endif
1110
1115 virtual ~NiftiImage () { release(); }
1116
1120 operator const nifti_image* () const { return image; }
1121
1125 operator nifti_image* () { return image; }
1126
1130 const nifti_image * operator-> () const { return image; }
1131
1135 nifti_image * operator-> () { return image; }
1136
1141 NiftiImage & operator= (const NiftiImage &source)
1142 {
1143 copy(source);
1144 #ifndef NDEBUG
1145 Rc_printf("Creating NiftiImage with pointer %p (from NiftiImage)\n", this->image);
1146 #endif
1147 return *this;
1148 }
1149
1155 NiftiImage & operator= (const Block &source)
1156 {
1157 copy(source);
1158 #ifndef NDEBUG
1159 Rc_printf("Creating NiftiImage with pointer %p (from Block)\n", this->image);
1160 #endif
1161 return *this;
1162 }
1163
1171 NiftiImage & setPersistence (const bool persistent) { return *this; }
1172
1177 bool isNull () const { return (image == NULL); }
1178
1183 bool isShared () const { return (refCount != NULL && *refCount > 1); }
1184
1191 bool isPersistent () const { return false; }
1192
1198 bool isDataScaled () const { return (image != NULL && image->scl_slope != 0.0 && (image->scl_slope != 1.0 || image->scl_inter != 0.0)); }
1199
1204 int nDims () const
1205 {
1206 if (image == NULL)
1207 return 0;
1208 else
1209 return image->ndim;
1210 }
1211
1216 std::vector<dim_t> dim () const
1217 {
1218 if (image == NULL)
1219 return std::vector<dim_t>();
1220 else
1221 return std::vector<dim_t>(image->dim+1, image->dim+image->ndim+1);
1222 }
1223
1228 std::vector<pixdim_t> pixdim () const
1229 {
1230 if (image == NULL)
1231 return std::vector<pixdim_t>();
1232 else
1233 return std::vector<pixdim_t>(image->pixdim+1, image->pixdim+image->ndim+1);
1234 }
1235
1242 NiftiImage & drop ()
1243 {
1244 int ndim = image->ndim;
1245 while (image->dim[ndim] < 2)
1246 ndim--;
1247 image->dim[0] = image->ndim = ndim;
1248
1249 return *this;
1250 }
1251
1256 const NiftiImageData data () const { return NiftiImageData(image); }
1257
1262 NiftiImageData data () { return NiftiImageData(image); }
1263
1273 template <typename TargetType>
1274 std::vector<TargetType> getData (const bool useSlope = true) const;
1275
1283 NiftiImage & changeDatatype (const int datatype, const bool useSlope = false);
1284
1292 NiftiImage & changeDatatype (const std::string &datatype, const bool useSlope = false);
1293
1302 template <typename SourceType>
1303 NiftiImage & replaceData (const std::vector<SourceType> &data, const int datatype = DT_NONE);
1304
1311 NiftiImage & replaceData (const NiftiImageData &data);
1312
1317 NiftiImage & dropData ()
1318 {
1319 #if RNIFTI_NIFTILIB_VERSION == 1
1320 nifti_image_unload(image);
1321 #elif RNIFTI_NIFTILIB_VERSION == 2
1322 nifti2_image_unload(image);
1323 #endif
1324 return *this;
1325 }
1326
1333 NiftiImage & rescale (const std::vector<pixdim_t> &scales);
1334
1343 NiftiImage & reorient (const int i, const int j, const int k);
1344
1353 NiftiImage & reorient (const std::string &orientation);
1354
1355 #ifdef USING_R
1356
1361 NiftiImage & update (const Rcpp::RObject &object);
1362 #endif
1363
1369 const Xform xform (const bool preferQuaternion = true) const;
1370
1371 const Xform qform () const { return (image == NULL ? Xform() : Xform(image->qto_xyz)); }
1372
1373 Xform qform () { return (image == NULL ? Xform() : Xform(image->qto_xyz, image->qto_ijk, &image->quatern_b)); }
1374
1375 const Xform sform () const { return (image == NULL ? Xform() : Xform(image->sto_xyz)); }
1376
1377 Xform sform () { return (image == NULL ? Xform() : Xform(image->sto_xyz, image->sto_ijk)); }
1378
1383 dim_t nBlocks () const { return (image == NULL ? 0 : image->dim[image->ndim]); }
1384
1392 const Block block (const int i) const { return Block(*this, nDims(), i); }
1393
1401 Block block (const int i) { return Block(*this, nDims(), i); }
1402
1408 const Block slice (const int i) const { return Block(*this, 3, i); }
1409
1415 Block slice (const int i) { return Block(*this, 3, i); }
1416
1422 const Block volume (const int i) const { return Block(*this, 4, i); }
1423
1429 Block volume (const int i) { return Block(*this, 4, i); }
1430
1436 int nChannels () const
1437 {
1438 if (image == NULL)
1439 return 0;
1440 else
1441 {
1442 switch (image->datatype)
1443 {
1444 case DT_NONE: return 0;
1445 case DT_RGB24: return 3;
1446 case DT_RGBA32: return 4;
1447 default: return 1;
1448 }
1449 }
1450 }
1451
1456 size_t nVoxels () const { return (image == NULL ? 0 : image->nvox); }
1457
1464 std::pair<std::string,std::string> toFile (const std::string fileName, const int datatype = DT_NONE) const;
1465
1472 std::pair<std::string,std::string> toFile (const std::string fileName, const std::string &datatype) const;
1473
1474 #ifdef USING_R
1475
1480 Rcpp::RObject toArray () const;
1481
1487 Rcpp::RObject toPointer (const std::string label) const;
1488
1495 Rcpp::RObject toArrayOrPointer (const bool internal, const std::string label) const;
1496
1501 Rcpp::RObject headerToList () const;
1502
1503 #endif
1504
1505 };
1506
1507 // Include image implementations
1508 #include "RNifti/NiftiImage_impl.h"
1509
1510 } // main namespace
1511
1512 #endif
RNifti::NiftiImage::NiftiImage
NiftiImage(const std::string &path, const std::vector< dim_t > &volumes)
Initialise using a path string and sequence of required volumes.
RNifti::NiftiImage::rescale
NiftiImage & rescale(const std::vector< pixdim_t > &scales)
Rescale the image, changing its image dimensions and pixel dimensions.
RNifti::NiftiImage::release
void release()
Release the currently wrapped pointer, if it is not NULL, decrementing the reference count and releas...
RNifti::NiftiImageData::isScaled
bool isScaled() const
Determine whether the object uses data scaling.
Definition: NiftiImage.h:528
RNifti::NiftiImage::Block
Inner class referring to a subset of an image.
Definition: NiftiImage.h:748
RNifti::NiftiImage::NiftiImage
NiftiImage(const Block &source)
Initialise from a block, copying in the data.
Definition: NiftiImage.h:1040
RNifti::NiftiImage::dim
std::vector< dim_t > dim() const
Return the dimensions of the image.
Definition: NiftiImage.h:1216
RNifti::NiftiImageData::isComplex
bool isComplex() const
Determine whether the datatype is complex.
Definition: NiftiImage.h:534
RNifti::NiftiImageData::operator=
NiftiImageData & operator=(const NiftiImageData &source)
Copy assignment operator.
Definition: NiftiImage.h:493
RNifti::NiftiImage::image
nifti_image * image
The wrapped nifti_image pointer.
Definition: NiftiImage.h:915
RNifti::NiftiImageData::Iterator
Iterator type for NiftiImageData, with Element as its value type.
Definition: NiftiImage.h:352
RNifti::NiftiImage::block
Block block(const int i)
Extract a block from the image.
Definition: NiftiImage.h:1401
RNifti::NiftiImage::volume
const Block volume(const int i) const
Extract a volume block from a 4D image.
Definition: NiftiImage.h:1422
RNifti::NiftiImage::dropData
NiftiImage & dropData()
Drop the data from the image, retaining only the metadata.
Definition: NiftiImage.h:1317
RNifti::NiftiImage::refCount
int * refCount
A reference counter, shared with other objects wrapping the same pointer.
Definition: NiftiImage.h:916
RNifti::NiftiImageData::Element::Element
Element(const NiftiImageData &parent, void *ptr=NULL)
Primary constructor.
Definition: NiftiImage.h:279
RNifti::NiftiImage::operator=
NiftiImage & operator=(const NiftiImage &source)
Copy assignment operator, which copies from its argument.
Definition: NiftiImage.h:1141
RNifti::NiftiImage::NiftiImage
NiftiImage(const std::string &path, const bool readData=true)
Initialise using a path string.
RNifti::NiftiImage::NiftiImage
NiftiImage(const NiftiImage &source, const bool copy=true)
Copy constructor.
Definition: NiftiImage.h:1024
RNifti::NiftiImage::changeDatatype
NiftiImage & changeDatatype(const int datatype, const bool useSlope=false)
Change the datatype of the image, casting the pixel data if present.
RNifti::NiftiImageData::NiftiImageData
NiftiImageData(void *data, const size_t length, const int datatype, const double slope=1.0, const double intercept=0.0)
Primary constructor.
Definition: NiftiImage.h:427
RNifti::NiftiImage::updatePixdim
void updatePixdim(const std::vector< pixdim_t > &pixdim)
Modify the pixel dimensions, and potentially the xform matrices to match.
RNifti::NiftiImageData::TypeHandler
Abstract inner class defining the type-specific functions required in concrete subclasses.
Definition: NiftiImage.h:81
RNifti::NiftiImageData::end
const Iterator end() const
Obtain a constant iterator corresponding to the end of the blob.
Definition: NiftiImage.h:571
RNifti::NiftiImage
Thin wrapper around a C-style nifti_image struct that allows C++-style destruction.
Definition: NiftiImage.h:731
RNifti::rgba32_t
Simple RGB(A) type encapsulating an 8-bit colour value with optional opacity, which can also be set o...
Definition: NiftiImage.h:54
RNifti::NiftiImageData::NiftiImageData
NiftiImageData(InputIterator from, InputIterator to, const int datatype)
Iterator-based constructor.
Definition: NiftiImage.h:471
RNifti::NiftiImageData::isFloatingPoint
bool isFloatingPoint() const
Determine whether the datatype is floating point.
Definition: NiftiImage.h:541
RNifti::NiftiImageData::size
size_t size() const
Return the number of elements in the data.
Definition: NiftiImage.h:509
RNifti::NiftiImage::isNull
bool isNull() const
Determine whether or not the wrapped pointer is NULL.
Definition: NiftiImage.h:1177
RNifti::NiftiImage::copy
void copy(const nifti_image *source)
Copy the contents of a nifti_image to create a new image, acquiring the new pointer.
RNifti::NiftiImage::setPixunits
void setPixunits(const std::vector< std::string > &pixunits)
Modify the pixel dimension units.
RNifti::NiftiImage::replaceData
NiftiImage & replaceData(const std::vector< SourceType > &data, const int datatype=DT_NONE)
Replace the pixel data in the image with the contents of a vector.
RNifti::NiftiImageData::length
size_t length() const
Return the number of elements in the data.
Definition: NiftiImage.h:508
RNifti::NiftiImageData::slope
double slope
The slope term used to scale data values.
Definition: NiftiImage.h:73
RNifti::NiftiImage::slice
Block slice(const int i)
Extract a slice block from a 3D image.
Definition: NiftiImage.h:1415
RNifti::NiftiImage::toPointer
Rcpp::RObject toPointer(const std::string label) const
Create an internal image to pass back to R.
RNifti::NiftiImageData::operator[]
const Element operator[](const size_t i) const
Indexing operator, returning a constant element.
Definition: NiftiImage.h:584
RNifti::NiftiImage::acquire
void acquire(const NiftiImage &source)
Acquire the same pointer as another NiftiImage, incrementing the shared reference count.
Definition: NiftiImage.h:930
RNifti::NiftiImageData::NiftiImageData
NiftiImageData(const NiftiImageData &source, const int datatype=DT_NONE)
Copy constructor with optional type conversion.
Definition: NiftiImage.h:451
RNifti::NiftiImage::isShared
bool isShared() const
Determine whether the wrapped pointer is shared with another NiftiImage.
Definition: NiftiImage.h:1183
RNifti::NiftiImageData::intercept
double intercept
The intercept term used to scale data values.
Definition: NiftiImage.h:74
RNifti::NiftiImage::nBlocks
dim_t nBlocks() const
Return the number of blocks in the image.
Definition: NiftiImage.h:1383
RNifti::NiftiImageData::end
Iterator end()
Obtain a mutable iterator corresponding to the end of the blob.
Definition: NiftiImage.h:577
RNifti::NiftiImage::toArrayOrPointer
Rcpp::RObject toArrayOrPointer(const bool internal, const std::string label) const
A conditional method that calls either toArray or toPointer.
RNifti::NiftiImage::toFile
std::pair< std::string, std::string > toFile(const std::string fileName, const int datatype=DT_NONE) const
Write the image to a NIfTI-1 file.
RNifti::NiftiImage::reorient
NiftiImage & reorient(const std::string &orientation)
Reorient the image by permuting dimensions and potentially reversing some.
RNifti::NiftiImage::getData
std::vector< TargetType > getData(const bool useSlope=true) const
Extract a vector of data from the image, casting it to any required element type.
RNifti::NiftiImageData::Element
Inner class representing a single element in the data blob.
Definition: NiftiImage.h:267
RNifti::NiftiImage::update
NiftiImage & update(const Rcpp::RObject &object)
Update the image from an R array.
RNifti::NiftiImage::data
const NiftiImageData data() const
Obtain the pixel data within the image.
Definition: NiftiImage.h:1256
RNifti::NiftiImage::reorient
NiftiImage & reorient(const int i, const int j, const int k)
Reorient the image by permuting dimensions and potentially reversing some.
RNifti::NiftiImageData::_length
size_t _length
The number of data elements in the blob.
Definition: NiftiImage.h:203
RNifti::NiftiImageData::isRgb
bool isRgb() const
Determine whether the datatype corresponds to an RGB type.
Definition: NiftiImage.h:553
RNifti::NiftiImage::NiftiImage
NiftiImage(nifti_image *const image, const bool copy=false)
Initialise using an existing nifti_image pointer.
Definition: NiftiImage.h:1055
RNifti::NiftiImageData
Wrapper class encapsulating a NIfTI data blob, with responsibility for handling data scaling and poly...
Definition: NiftiImage.h:71
RNifti::NiftiImage::toArray
Rcpp::RObject toArray() const
Create an R array from the image.
RNifti::NiftiImage::Block::data
NiftiImageData data() const
Obtain the data within the block.
Definition: NiftiImage.h:798
RNifti::NiftiImage::block
const Block block(const int i) const
Extract a block from the image.
Definition: NiftiImage.h:1392
RNifti::Vector
Definition: NiftiImage.h:622
RNifti::NiftiImageData::isInteger
bool isInteger() const
Determine whether the datatype is an integer type.
Definition: NiftiImage.h:547
RNifti::NiftiImage::setPersistence
NiftiImage & setPersistence(const bool persistent)
Mark the image as persistent, so that it can be passed back to R.
Definition: NiftiImage.h:1171
RNifti::NiftiImage::replaceData
NiftiImage & replaceData(const NiftiImageData &data)
Replace the pixel data in the image with the contents of a NiftiImageData object.
RNifti::NiftiImage::volume
Block volume(const int i)
Extract a volume block from a 4D image.
Definition: NiftiImage.h:1429
RNifti::NiftiImageData::unscaled
NiftiImageData unscaled() const
Return a similar object to the callee, but with the slope and intercept values reset.
Definition: NiftiImage.h:559
RNifti::NiftiImage::~NiftiImage
virtual ~NiftiImage()
Destructor which decrements the reference counter, and releases the wrapped pointer if the counter dr...
Definition: NiftiImage.h:1115
RNifti::NiftiImage::changeDatatype
NiftiImage & changeDatatype(const std::string &datatype, const bool useSlope=false)
Change the datatype of the image, casting the pixel data if present.
RNifti::NiftiImageData::disown
NiftiImageData & disown()
Disown the data blob, removing responsibility for freeing it upon destruction.
Definition: NiftiImage.h:565
RNifti::NiftiImage::isDataScaled
bool isDataScaled() const
Determine whether nontrivial scale and slope parameters are set.
Definition: NiftiImage.h:1198
RNifti::NiftiImage::acquire
void acquire(nifti_image *const image)
Acquire the specified pointer to a nifti_image struct, taking (possibly shared) responsibility for fr...
RNifti::NiftiImageData::begin
Iterator begin()
Obtain a mutable iterator corresponding to the start of the blob.
Definition: NiftiImage.h:574
RNifti::NiftiImage::xform
const Xform xform(const bool preferQuaternion=true) const
Obtain an xform matrix, indicating the orientation of the image.
RNifti::NiftiImageData::ConcreteTypeHandler
Concrete inner class template defining behaviour specific to individual data types.
Definition: NiftiImage.h:101
RNifti::NiftiImage::Block::index
const dim_t index
The location along dimension.
Definition: NiftiImage.h:751
RNifti::NiftiImageData::createHandler
TypeHandler * createHandler()
Create a concrete type handler appropriate to the datatype code stored with the data.
Definition: NiftiImage.h:173
RNifti::rgba32_t::ValueType
Definition: NiftiImage.h:55
RNifti::NiftiImage::fileVersion
static int fileVersion(const std::string &path)
Get the NIfTI format version used by the file at the specified path.
RNifti::NiftiImage::Block::getData
std::vector< TargetType > getData(const bool useSlope=true) const
Extract a vector of data from a block, casting it to any required element type.
RNifti::NiftiImage::NiftiImage
NiftiImage()
Default constructor.
Definition: NiftiImage.h:1015
RNifti::NiftiImage::operator->
const nifti_image * operator->() const
Allows a NiftiImage object to be treated as a pointer to a const nifti_image.
Definition: NiftiImage.h:1130
RNifti::NiftiImageData::dataPtr
void * dataPtr
Opaque pointer to the underlying data blob.
Definition: NiftiImage.h:200
RNifti::NiftiImageData::datatype
int datatype() const
Return stored datatype code.
Definition: NiftiImage.h:507
RNifti::NiftiImage::Block::operator=
Block & operator=(const NiftiImage &source)
Copy assignment operator, which allows a block in one image to be replaced with the contents of anoth...
Definition: NiftiImage.h:775
RNifti::NiftiImageData::handler
TypeHandler * handler
Type handler, which is created to match the datatype.
Definition: NiftiImage.h:202
RNifti::NiftiImage::nVoxels
size_t nVoxels() const
Return the number of voxels in the image.
Definition: NiftiImage.h:1456
RNifti::NiftiImageData::totalBytes
size_t totalBytes() const
Return the total size of the data blob, in bytes.
Definition: NiftiImage.h:515
RNifti::NiftiImageData::calibrateFrom
void calibrateFrom(const NiftiImageData &data)
Update the slope and intercept to cover the range of another data object.
Definition: NiftiImage.h:242
RNifti::NiftiImage::initFromMriImage
void initFromMriImage(const Rcpp::RObject &object, const bool copyData=true)
Initialise the object from a reference object of class "MriImage".
RNifti::NiftiImageData::bytesPerPixel
size_t bytesPerPixel() const
Return the number of bytes used per element, or zero if the datatype is undefined or the blob is NULL...
Definition: NiftiImage.h:512
RNifti::NiftiImageData::init
void init(void *data, const size_t length, const int datatype, const double slope, const double intercept, const bool alloc=true)
Initialiser method, used by constructors.
Definition: NiftiImage.h:216
RNifti::NiftiImage::Xform
Definition: NiftiImage.h:823
RNifti::NiftiImageData::owner
bool owner
An indicator of whether this object is responsible for cleaning up the data.
Definition: NiftiImage.h:204
RNifti::NiftiImage::toFile
std::pair< std::string, std::string > toFile(const std::string fileName, const std::string &datatype) const
Write the image to a NIfTI-1 file.
RNifti::SquareMatrix
Definition: NiftiImage.h:652
RNifti::NiftiImage::Block::image
const NiftiImage & image
The parent image.
Definition: NiftiImage.h:749
RNifti::NiftiImageData::NiftiImageData
NiftiImageData(nifti_image *image)
Convenience constructor for a nifti_image.
Definition: NiftiImage.h:436
RNifti::NiftiImageData::blob
void * blob() const
Return an opaque pointer to the blob.
Definition: NiftiImage.h:506
RNifti::NiftiImage::NiftiImage
NiftiImage(const std::vector< dim_t > &dim, const std::string &datatype)
Initialise from basic metadata, allocating and zeroing pixel data.
RNifti::NiftiImage::pixdim
std::vector< pixdim_t > pixdim() const
Return the dimensions of the pixels or voxels in the image.
Definition: NiftiImage.h:1228
RNifti::NiftiImageData::minmax
void minmax(double *min, double *max) const
Calculate the minimum and maximum values in the blob, as doubles.
Definition: NiftiImage.h:600
RNifti::NiftiImage::nDims
int nDims() const
Return the number of dimensions in the image.
Definition: NiftiImage.h:1204
RNifti::NiftiImageData::Iterator::Iterator
Iterator(const Iterator &other)
Copy constructor.
Definition: NiftiImage.h:377
RNifti::NiftiImage::NiftiImage
NiftiImage(const SEXP object, const bool readData=true, const bool readOnly=false)
Initialise from an R object, retrieving an existing image from an external pointer attribute if avail...
RNifti::NiftiImageData::Iterator::Iterator
Iterator(const NiftiImageData &parent, void *ptr=NULL, const size_t step=0)
Primary constructor.
Definition: NiftiImage.h:366
RNifti::NiftiImage::drop
NiftiImage & drop()
Drop unitary dimensions.
Definition: NiftiImage.h:1242
RNifti::NiftiImage::initFromNiftiS4
void initFromNiftiS4(const Rcpp::RObject &object, const bool copyData=true)
Initialise the object from an S4 object of class "nifti".
RNifti::NiftiImage::initFromArray
void initFromArray(const Rcpp::RObject &object, const bool copyData=true)
Initialise the object from an R array.
RNifti::NiftiImage::initFromList
void initFromList(const Rcpp::RObject &object)
Initialise the object from an R list with named elements, which can only contain metadata.
RNifti::NiftiImage::data
NiftiImageData data()
Obtain the pixel data within the image.
Definition: NiftiImage.h:1262
RNifti::NiftiImage::nChannels
int nChannels() const
Return the number of colour channels used by the image.
Definition: NiftiImage.h:1436
RNifti::NiftiImage::copy
void copy(const NiftiImage &source)
Copy the contents of another NiftiImage to create a new image, acquiring a new pointer.
RNifti::NiftiImage::Block::dimension
const int dimension
The dimension along which the block applies (which should be the last)
Definition: NiftiImage.h:750
RNifti::NiftiImage::Block::Block
Block(const NiftiImage &image, const int dimension, const dim_t index)
Standard constructor for this class.
Definition: NiftiImage.h:760
RNifti::NiftiImage::slice
const Block slice(const int i) const
Extract a slice block from a 3D image.
Definition: NiftiImage.h:1408
RNifti::NiftiImage::headerToList
Rcpp::RObject headerToList() const
Create an R list containing raw image metadata.
RNifti::NiftiImage::isPersistent
bool isPersistent() const
Determine whether or not the image is marked as persistent.
Definition: NiftiImage.h:1191
RNifti::NiftiImageData::Element::operator=
Element & operator=(const SourceType &value)
Copy assignment operator.
RNifti::NiftiImageData::~NiftiImageData
virtual ~NiftiImageData()
Destructor which frees the type handler, and the data blob if it is owned by this object.
Definition: NiftiImage.h:481
RNifti::NiftiImageData::isEmpty
bool isEmpty() const
Determine whether or not the object is empty.
Definition: NiftiImage.h:521
RNifti::NiftiImageData::begin
const Iterator begin() const
Obtain a constant iterator corresponding to the start of the blob.
Definition: NiftiImage.h:568
RNifti::NiftiImageData::NiftiImageData
NiftiImageData()
Default constructor, creating an empty data object.
Definition: NiftiImage.h:415
RNifti::NiftiImage::initFromDims
void initFromDims(const std::vector< dim_t > &dim, const int datatype)
Initialise an empty object from basic metadata.
RNifti::NiftiImage::copy
void copy(const Block &source)
Copy the contents of a Block to create a new image, acquiring a new pointer.
RNifti::NiftiImage::NiftiImage
NiftiImage(const std::vector< dim_t > &dim, const int datatype)
Initialise from basic metadata, allocating and zeroing pixel data.
RNifti::NiftiImageData::_datatype
int _datatype
Datatype code indicating the actual type of the elements.
Definition: NiftiImage.h:201
RNifti::NiftiImage::sexpTypeToNiftiType
static int sexpTypeToNiftiType(const int sexpType)
Convert between R SEXP object type and nifti_image datatype codes.
Definition: NiftiImage.h:892