00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __NRRO_DOT_H
00023 #define __NRRO_DOT_H
00024
00025 #include <nrrd.h>
00026 #include <arrayGutz.h>
00027 #include <mathGutz.h>
00028 #include <smartptr.h>
00029 #include <iostream>
00030 #include <vector>
00031 #include <string>
00032 #include "nrroKernel.h"
00033
00034 #define MAX_NRRO_ARRAY_DIM 8
00035
00036 class NrroProbe;
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 class Nrro : public gutz::Counted {
00050 public:
00051 Nrro();
00052 Nrro(int typeEnum, int sx);
00053 Nrro(int typeEnum, int sx, int sy);
00054 Nrro(int typeEnum, int sx, int sy, int sz);
00055 Nrro(int typeEnum, int sx, int sy, int sz, int sw);
00056 Nrro(int typeEnum, int s1, int s2, int s3, int s4, int s5);
00057 Nrro(int typeEnum, int dim, int sz[]);
00058 Nrro(const Nrro &n);
00059 Nrro(const char* nrrdFileName, bool proxy = false);
00060 Nrro(Nrrd* n);
00061 virtual ~Nrro();
00062
00063
00064
00065 void operator=(const Nrro &n);
00066
00067
00068
00069 bool isValid() const {return _valid;}
00070
00071
00072
00073
00074
00075 bool isModified() const {return _modified;}
00076 void setModified(bool mod = true) {_modified = mod;}
00077
00078
00079
00080
00081
00082
00083
00084 virtual void update();
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 enum NRRO_KINDS{
00099 KIND_NOT_SET = 0,
00100 KIND_UNKNOWN = 1<<0,
00101 IMAGE = 1<<1,
00102 VOLUME = 1<<2,
00103 TIME_SERIES = 1<<3,
00104 PROXY = 1<<4,
00105 KIND_LAST = 1<<5 | 1<<0
00106 };
00107 int getKind() const {return _kind;}
00108
00109 int guessKind() const;
00110
00111
00112
00113
00114
00115 void setKind(int kind) {_kind = kind;}
00116
00117 void printKind() const;
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 enum NRRO_TYPES {
00130 UNKNOWN = nrrdTypeUnknown,
00131 CHAR = nrrdTypeChar,
00132 UCHAR = nrrdTypeUChar,
00133 SHORT = nrrdTypeShort,
00134 USHORT = nrrdTypeUShort,
00135 INT = nrrdTypeInt,
00136 UINT = nrrdTypeUInt,
00137 FLOAT = nrrdTypeFloat,
00138 DOUBLE = nrrdTypeDouble,
00139 BLOCK = nrrdTypeBlock,
00140 TYPE_LAST = nrrdTypeLast
00141 };
00142
00143
00144
00145
00146 int getType() const {if(_nrrd)return _nrrd->type; return UNKNOWN;}
00147 void printType() const;
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 virtual int readNrrd(const char *nrrdFileName, bool proxy = false);
00160
00161 virtual int saveNrrd(const char *nrrdFileName);
00162
00163
00164
00165
00166
00167
00168
00169
00170 Nrrd* getNrrd() const {assert(_nrrd); return _nrrd;}
00171 void setNrrd(Nrrd *n);
00172
00173
00174
00175
00176
00177 void* getData() const {return _nrrd->data;}
00178
00179
00180
00181
00182
00183
00184
00185 int dim() const {return _nrrd->dim;}
00186
00187 int dim(int a) const {return _nrrd->axis[a].size;}
00188
00189 int dimNPad(int a) const {return _pads[a].y - _pads[a].x + 1;}
00190
00191 float axisSize(int a) const {return float(dim(a)-1) * axisSpacing(a);}
00192
00193 float axisSizeNPad(int a) const;
00194
00195 float axisSpacing(int a) const {return float(_nrrd->axis[a].spacing);}
00196 void setAxisSpacing(int a, float s) {_nrrd->axis[a].spacing = s;}
00197
00198 char* axisName(int a) const {return _nrrd->axis[a].label;}
00199
00200 char* axisUnit(int a) const {return _nrrd->axis[a].unit;}
00201
00202 gutz::vec2ui axisValNPad(int a) const {return _pads[a];}
00203
00204 int size() const;
00205
00206 int getStride(int a) const { return _strides[a]; }
00207
00208 gutz::vec2d getMinMax() const { return _minmax; }
00209
00210
00211
00212
00213
00214
00215
00216
00217 gutz::vec3f getPos() const {return _pos;}
00218 void setPos(gutz::vec3f pos) {_pos = pos;}
00219
00220 gutz::vec3f getSizeV3() const;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 gutz::SmartPtr<Nrro> quantize(int bits, double min = AIR_NAN, double max = AIR_NAN);
00233
00234
00235
00236 gutz::SmartPtr<Nrro> slice(int axis, int pos);
00237
00238
00239
00240
00241 gutz::SmartPtr<Nrro> crop(int min[], int max[]);
00242
00243
00244
00245 enum NRRO_BOUNDARY_BEHAVIORS{
00246 PAD = nrrdBoundaryPad,
00247 BLEED = nrrdBoundaryBleed,
00248 WRAP = nrrdBoundaryWrap
00249 };
00250
00251
00252 gutz::SmartPtr<Nrro> pad(int min[], int max[], int bound = PAD, double padval = 0.0);
00253
00254
00255
00256 gutz::SmartPtr<Nrro> cropPad(int min[], int max[], int bound = PAD, double padval = 0.0);
00257
00258
00259
00260
00261
00262
00263
00264 gutz::SmartPtr<Nrro> resample(int dims[],
00265 const NrroKernel &kern = CatmulRomKernel,
00266 int bound = BLEED,
00267 int typeOut = UNKNOWN);
00268 gutz::SmartPtr<Nrro> resample(float pct = 1.0f);
00269
00270
00271
00272 int insertAxis(unsigned int axis);
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 int forceMultiChannel();
00285
00286
00287
00288
00289
00290 std::string getName() const {return _name;}
00291 void setName(std::string name) {_name = name;}
00292
00293
00294
00295
00296 void printInfo() const;
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int numComments() const;
00310 std::string getComment(int i);
00311 std::string getComment(const std::string key);
00312 void addComment(const std::string comment);
00313 void addComment(const std::string key, const std::string comment);
00314 void setComment(int i, const std::string comment);
00315 void setComment(const std::string key, const std::string comment);
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 class __dbl {
00327 public:
00328 __dbl(Nrro *n, int pos) : _n(n), _pos(pos) {}
00329 ~__dbl(){}
00330 double operator=(const __dbl &vp);
00331
00332 double operator=(double v) {return assn<double>(v);}
00333 float operator=(float v) {return assn<float>(v);}
00334 unsigned short operator=(unsigned short v) {return assn<unsigned short>(v);}
00335 short operator=(short v) {return assn<short>(v);}
00336 unsigned int operator=(unsigned int v) {return assn<unsigned int>(v);}
00337 int operator=(int v) {return assn<int>(v);}
00338 char operator=(char v) {return assn<char>(v);}
00339 double operator+=(double v) {return assn<double>(val() + v);}
00340 double operator-=(double v) {return assn<double>(val() - v);}
00341 double operator++() {return assn<double>(val() + 1);}
00342 double operator--() {return assn<double>(val() - 1);}
00343 double val() const;
00344 template<class T>
00345 T assn(T val);
00346
00347 operator double() const {return val();}
00348 protected:
00349 Nrro *_n;
00350 int _pos;
00351 };
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 double v(int i1) const {return val<double>(i1);}
00368 double operator()(int i1) const {return v(i1);}
00369 __dbl v(int i1) {return __dbl(this,i1);}
00370 __dbl operator()(int i1) {return v(i1);}
00371 double v(int i1, int i2) const {return val<double>(a(i1, i2));}
00372 double operator()(int i1, int i2) const {return v(i1, i2);}
00373 __dbl v(int i1, int i2) {return __dbl(this,a(i1,i2));}
00374 __dbl operator()(int i1, int i2) {return v(i1,i2);}
00375 double v(int i1, int i2, int i3, int i4=0) const;
00376 double operator()(int i1, int i2, int i3, int i4=0) const {return v(i1,i2,i3,i4);}
00377 __dbl v(int i1, int i2, int i3, int i4=0);
00378 __dbl operator()(int i1, int i2, int i3, int i4=0) {return v(i1,i2,i3,i4);}
00379 double v(int i1, int i2, int i3, int i4, int i5, int i6=0) const;
00380 double operator()(int i1, int i2, int i3, int i4, int i5, int i6=0) const;
00381 __dbl v(int i1, int i2, int i3, int i4, int i5, int i6=0);
00382 __dbl operator()(int i1, int i2, int i3, int i4, int i5, int i6=0);
00383 template<class T>
00384 T val(int pos) const;
00385
00386 int a(int i1, int i2=0) const {return i1 + i2*getStride(1);}
00387 int a(int i1,int i2, int i3, int i4=0) const;
00388 int a(int i1, int i2, int i3, int i4, int i5, int i6=0) const;
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 template<class T>
00400 class NrroIter {
00401 public:
00402 NrroIter(Nrro *n, int pos = 0);
00403 NrroIter(const NrroIter &ni);
00404 virtual ~NrroIter(){}
00405 T &operator*() {return *_d;}
00406 const T &operator*() const {return *_d;}
00407 Nrro *operator->() {return _n.getPtr();}
00408 const Nrro *operator->() const {return _n.getPtr();}
00409 NrroIter &operator=(const NrroIter &ni);
00410 NrroIter &operator=(int pos) {_d = _n.getData() + pos; return *this;}
00411 const NrroIter &operator+=(int dpos) const{_d += dpos; _pos += dpos; return *this;}
00412 NrroIter &operator+=(int dpos) {_d += dpos; _pos += dpos; return *this;}
00413 const NrroIter &operator-=(int dpos) const{_d -= dpos; _pos -= dpos; return *this;}
00414 NrroIter &operator-=(int dpos) {_d -= dpos; _pos -= dpos; return *this;}
00415 bool operator==(const NrroIter &ni) const;
00416 bool operator!=(const NrroIter &ni) const {return (! (*this) == ni );}
00417 bool operator>(const NrroIter &ni) const {return _pos > ni._pos;}
00418 bool operator<(const NrroIter &ni) const {return _pos < ni._pos;}
00419 bool operator>=(const NrroIter &ni) const {return _pos >= ni._pos;}
00420 bool operator<=(const NrroIter &ni) const {return _pos <= ni._pos;}
00421 bool isValid() const
00422 {return ((_pos >= 0) && (_pos < int(_n->size())));}
00423 const NrroIter &operator++() const {++_d; ++_pos; return *this;}
00424 NrroIter &operator++() {++_d; ++_pos; return *this;}
00425 const NrroIter operator++(int) const
00426 {NrroIter<T> tmp = *this; ++(*this); return tmp;}
00427 NrroIter operator++(int)
00428 {NrroIter<T> tmp = *this; ++(*this); return tmp;}
00429 const NrroIter &operator--() const {--_d; --_pos; return *this;}
00430 NrroIter &operator--() {--_d; --_pos; return *this;}
00431 const NrroIter operator--(int) const
00432 {NrroIter<T> tmp = *this; --*this; return tmp;}
00433 NrroIter operator--(int)
00434 {NrroIter<T> tmp = *this; --*this; return tmp;}
00435 const NrroIter operator+(int dpos) const
00436 {return NrroIter<T>(const_cast<Nrro*>(_n.getPtr()),_pos+dpos); }
00437 NrroIter operator+(int dpos) {return NrroIter<T>(_n,_pos+dpos); }
00438 const NrroIter operator-(int dpos) const
00439 {return NrroIter<T>(const_cast<Nrro*>(_n.getPtr()),_pos-dpos); }
00440 NrroIter operator-(int dpos) {return NrroIter<T>(_n,_pos-dpos); }
00441
00442 int operator-(const NrroIter &ni) const {return _pos - ni._pos; }
00443
00444 T &operator[](int pos) {return (*(*this + pos));}
00445 T operator[](int pos) const {return (*(*this + pos));}
00446
00447
00448 T operator()(int i1) const {return ((T*)(_n->getData()))[i1];}
00449 T &operator()(int i1) {return ((T*)(_n->getData()))[i1];}
00450 T operator()(int i1, int i2) const;
00451 T &operator()(int i1, int i2);
00452 T operator()(int i1, int i2, int i3, int i4=0) const;
00453 T &operator()(int i1, int i2, int i3, int i4=0);
00454 T operator()(int i1, int i2, int i3, int i4, int i5, int i6=0) const;
00455 T &operator()(int i1, int i2, int i3, int i4, int i5, int i6=0);
00456 int pos() const {return _pos;}
00457 protected:
00458 gutz::SmartPtr<Nrro> _n;
00459 mutable int _pos;
00460 mutable T* _d;
00461 private:
00462 NrroIter();
00463 };
00464
00465
00466
00467
00468
00469
00470
00471 template<class T>
00472 NrroIter<T> begin() { return NrroIter<T>(this, 0); }
00473 template<class T>
00474 NrroIter<T> last() { return NrroIter<T>(this, int(size())-1); }
00475 template<class T>
00476 const NrroIter<T> end() const { return NrroIter<T>(this,int(size())); }
00477
00478
00479
00480
00481
00482
00483
00484 virtual void setStrides();
00485
00486
00487 protected:
00488
00489 virtual void initMembers();
00490
00491 virtual void erase();
00492
00493 virtual void copy(const Nrro &n);
00494
00495 inline
00496 void NrroErr(const char *s, const char *s2=0) const;
00497
00498 inline
00499 void NrroDbg(const char *s, const char *s2=0) const;
00500
00501
00502
00503
00504
00505
00506
00507
00508 virtual void readExtended();
00509 virtual void writeExtended();
00510
00511
00512
00513
00514
00515
00516 Nrrd *_nrrd;
00517
00518
00519
00520
00521
00522
00523
00524 int _kind;
00525 virtual void writeKind();
00526 virtual void readKind();
00527
00528
00529 gutz::arrayo1v2ui _pads;
00530 virtual void writePads();
00531 virtual void readPads();
00532
00533
00534
00535 gutz::vec3f _pos;
00536 virtual void writePos();
00537 virtual void readPos();
00538
00539
00540 std::string _name;
00541 virtual void writeName();
00542 virtual void readName();
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 int _strides[MAX_NRRO_ARRAY_DIM];
00553
00554
00555 bool _valid;
00556 bool _modified;
00557
00558
00559 std::string _fileName;
00560
00561
00562
00563 void updateMinMax();
00564 gutz::vec2d _minmax;
00565 unsigned int _size;
00566 private:
00567
00568 };
00569
00570
00571
00572
00573
00574 typedef gutz::SmartPtr<Nrro> NrroSP;
00575 typedef std::vector<NrroSP> NrroSPVec;
00576 typedef std::vector<NrroSP>::iterator NrroSPVecIter;
00577
00578
00579
00580
00581 extern const std::string NRRO_KIND_KEY;
00582 extern const std::string NRRO_PADS_KEY;
00583 extern const std::string NRRO_POS_KEY;
00584 extern const std::string NRRO_NAME_KEY;
00585
00586
00587
00588
00589
00590
00591
00592 inline
00593 void Nrro::NrroErr(const char *s, const char *s2) const
00594 {
00595 std::cerr << " -";
00596 if(!_name.empty())
00597 std::cerr << _name;
00598 else
00599 std::cerr << "Un-named Nrro";
00600 std::cerr << std::endl;
00601
00602 std::cerr << "Error, Nrro::" << s;
00603 if(s2) std::cerr << " : " << s2;
00604 std::cerr << std::endl;
00605 }
00606
00607 inline
00608 void Nrro::NrroDbg(const char *s, const char *s2) const
00609 {
00610 #ifdef _DEBUG
00611 std::cerr << " -";
00612 if(!_name.empty())
00613 std::cerr << _name;
00614 else
00615 std::cerr << "Un-named Nrro";
00616 std::cerr << std::endl;
00617
00618 std::cerr << "Debug, Nrro::" << s;
00619 if(s2) std::cerr << " : " << s2;
00620 std::cerr << std::endl;
00621 #endif
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 template <class T>
00635 inline
00636 T Nrro::val(int pos) const
00637 {
00638 switch(getType())
00639 {
00640 case Nrro::CHAR:
00641 return T( ( ((char*)getData())[pos] ) );
00642 break;
00643 case Nrro::UCHAR:
00644 return T( ( ((unsigned char*)getData())[pos] ) );
00645 break;
00646 case Nrro::SHORT:
00647 return T( ( ((short*)getData())[pos] ) );
00648 break;
00649 case Nrro::USHORT:
00650 return T( ( ((unsigned short*)getData())[pos] ) );
00651 break;
00652 case Nrro::INT:
00653 return T( ( ((int*)getData())[pos]) );
00654 break;
00655 case Nrro::UINT:
00656 return T( ( ((unsigned int*)getData())[pos] ) );
00657 break;
00658 case Nrro::FLOAT:
00659 return T( ( ((float*)getData())[pos] ) );
00660 break;
00661 case Nrro::DOUBLE:
00662 return T( ( ((double*)getData())[pos] ) );
00663 break;
00664 }
00665 return 0.0;
00666 }
00667
00668 inline
00669 int Nrro::a(int i1,int i2, int i3, int i4) const
00670 {
00671 return a(i1,i2) + i3*getStride(2) + i4*getStride(3);
00672 }
00673
00674 inline
00675 double Nrro::v(int i1, int i2, int i3, int i4) const
00676 {
00677 return val<double>(a(i1,i2,i3,i4));
00678 }
00679
00680 inline
00681 Nrro::__dbl Nrro::v(int i1, int i2, int i3, int i4)
00682 {
00683 return __dbl(this,a(i1,i2,i3,i4));
00684 }
00685
00686 inline
00687 int Nrro::a(int i1, int i2, int i3, int i4, int i5, int i6) const
00688 {
00689 return a(i1,i2,i3,i4) + i5*getStride(4) + i6*getStride(5);
00690 }
00691
00692 inline
00693 double Nrro::v(int i1, int i2, int i3, int i4, int i5, int i6) const
00694 {
00695 return val<double>(a(i1,i2,i3,i4,i5,i6));
00696 }
00697
00698 inline
00699 Nrro::__dbl Nrro::v(int i1, int i2, int i3, int i4, int i5, int i6)
00700 {
00701 return __dbl(this,a(i1,i2,i3,i4,i5,i6));
00702 }
00703
00704 inline
00705 double Nrro::operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
00706 {
00707 return v(i1,i2,i3,i4,i5,i6);
00708 }
00709
00710 inline
00711 Nrro::__dbl Nrro::operator()(int i1, int i2, int i3, int i4, int i5, int i6)
00712 {
00713 return v(i1,i2,i3,i4,i5,i6);
00714 }
00715
00716
00717
00718
00719 inline
00720 double Nrro::__dbl::val() const
00721 {
00722 return _n->val<double>(_pos);
00723 }
00724
00725 inline
00726 double Nrro::__dbl::operator=(const __dbl &vp)
00727 {
00728 return operator=(vp.val());
00729 }
00730
00731
00732
00733
00734
00735
00736
00737
00738 template<class T>
00739 inline
00740 T Nrro::__dbl::assn(T val)
00741 {
00742
00743
00744 switch(_n->getType())
00745 {
00746 case Nrro::CHAR:
00747
00748
00749
00750
00751
00752
00753 return T( (*( ((char*)_n->getData()) + _pos) ) = (char)val );
00754 break;
00755 case Nrro::UCHAR:
00756 return T((*(((char*)_n->getData()) + _pos)) = (char)val);
00757 break;
00758 case Nrro::SHORT:
00759 return T((*(((short*)_n->getData()) + _pos)) = (short)val);
00760 break;
00761 case Nrro::USHORT:
00762 return T((*(((unsigned short*)_n->getData()) + _pos)) = (unsigned short)val);
00763 break;
00764 case Nrro::INT:
00765 return T((*(((int*)_n->getData()) + _pos)) = (int)val);
00766 break;
00767 case Nrro::UINT:
00768 return T((*(((unsigned int*)_n->getData()) + _pos)) = (unsigned int)val);
00769 break;
00770 case Nrro::FLOAT:
00771 return T((*(((float*)_n->getData()) + _pos)) = (float)val);
00772 break;
00773 case Nrro::DOUBLE:
00774 return T((*(((double*)_n->getData()) + _pos)) = val);
00775 break;
00776 }
00777 return val;
00778 }
00779
00780
00781
00782
00783 template<class T>
00784 Nrro::NrroIter<T>::
00785 NrroIter(Nrro *n, int pos)
00786 : _pos(pos), _n(gutz::SmartPtr<Nrro>(n))
00787 {
00788 if(!n)
00789 {
00790 std::cerr << "NrroIter::NrroIter(), null nrro!!!" << std::endl;
00791 _d = 0;
00792 }
00793 else
00794 {
00795 _d = (T*)(n->getData());
00796 }
00797 }
00798
00799 template<class T>
00800 Nrro::NrroIter<T>::
00801 NrroIter(const NrroIter &ni)
00802 : _d(ni._d), _pos(ni._pos), _n(ni._n)
00803 {}
00804
00805 template<class T>
00806 Nrro::NrroIter<T> &Nrro::NrroIter<T>::
00807 operator=(const NrroIter<T> &ni)
00808 {
00809 _d = ni._d;
00810 _n = ni._n;
00811 _pos = ni._pos;
00812 return this;
00813 }
00814
00815 template<class T>
00816 bool Nrro::NrroIter<T>::
00817 operator==(const NrroIter<T> &ni) const
00818 {
00819 if(ni._pos != _pos) return false;
00820 if(ni._n != _n) return false;
00821 return true;
00822 }
00823
00824 template<class T>
00825 inline
00826 T &Nrro::NrroIter<T>::
00827 operator()(int i1, int i2, int i3, int i4, int i5, int i6)
00828 {
00829 return ((T*)(_n->getData()))[ _n->a(i1,i2,i3,i4,i5,i6) ];
00830 }
00831
00832 template<class T>
00833 inline
00834 T Nrro::NrroIter<T>::
00835 operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
00836 {
00837 return ((T*)(_n->getData()))[ _n->a(i1,i2,i3,i4,i5,i6) ];
00838 }
00839
00840 template<class T>
00841 inline
00842 T &Nrro::NrroIter<T>::
00843 operator()(int i1, int i2)
00844 {
00845 return ((T*)(_n->getData()))[ _n->a(i1,i2) ];
00846 }
00847
00848 template<class T>
00849 inline
00850 T Nrro::NrroIter<T>::
00851 operator()(int i1, int i2) const
00852 {
00853 return ((T*)(_n->getData()))[ _n->a(i1,i2) ];
00854 }
00855
00856 template<class T>
00857 inline
00858 T &Nrro::NrroIter<T>::
00859 operator()(int i1, int i2, int i3, int i4)
00860 {
00861 return *(((T*)(_n->getData()))+_n->a(i1,i2,i3,i4));
00862 }
00863
00864 template<class T>
00865 inline
00866 T Nrro::NrroIter<T>::
00867 operator()(int i1, int i2, int i3, int i4) const
00868 {
00869 return *(((T*)(_n->getData())) + _n->a(i1,i2,i3,i4));
00870 }
00871
00872
00873
00874
00875 #endif
00876