1 #ifndef __MINC_1_SIMPLE_H__
2 #define __MINC_1_SIMPLE_H__
3 
4 #include "minc_1_rw.h"
5 
6 namespace minc
7 {
8 
9   template <class T> class minc_input_iterator
10   {
11     protected:
12       mutable minc_1_reader* _rw;
13       std::vector<T> _buf;
14       std::vector<long> _cur;
15       bool _last;
16       size_t _count;
17     public:
18 
cur(void)19     const std::vector<long>& cur(void) const
20     {
21       return _cur;
22     }
23 
24 
minc_input_iterator(const minc_input_iterator<T> & a)25     minc_input_iterator(const minc_input_iterator<T>& a):_rw(a._rw),_cur(a._cur),_last(a._last),_count(a._count)
26     {
27     }
28 
minc_input_iterator(minc_1_reader & rw)29     minc_input_iterator(minc_1_reader& rw):_rw(&rw),_last(false),_count(0)
30     {
31     }
32 
minc_input_iterator()33     minc_input_iterator():_rw(NULL),_last(false),_count(0)
34     {
35     }
36 
attach(minc_1_reader & rw)37     void attach(minc_1_reader& rw)
38     {
39       _rw=&rw;
40       _last=false;
41       _count=0;
42     }
43 
next(void)44     bool next(void)
45     {
46       if(_last) return false;
47       _count++;
48       for(size_t i=static_cast<size_t>(_rw->dim_no()-1);
49 	  i>static_cast<size_t>(_rw->dim_no()-_rw->slice_dimensions()-1);i--)
50       {
51         _cur[i]++;
52         if(_cur[i]<static_cast<long>(_rw->dim(i).length))
53           break;
54         if(i>static_cast<size_t>(_rw->dim_no()-_rw->slice_dimensions()))
55           _cur[i]=0;
56         else
57         {
58           //move to next slice
59           if(i==0) // the case when slice_dimensions==dim_no
60           {
61             _last=true;
62             _count=0;
63             break;
64           }
65           if(!_rw->next_slice())
66           {
67             _last=true;
68             break;
69           }
70           _rw->read(&_buf[0]);
71           _cur=_rw->current_slice();
72           _count=0;
73           break;
74         }
75       }
76       return !_last;
77     }
78 
last(void)79     bool last(void)
80     {
81       return _last;
82     }
83 
begin(void)84     void begin(void)
85     {
86       _cur.resize(MAX_VAR_DIMS,0);
87       _buf.resize(_rw->slice_len());
88       _count=0;
89       _rw->begin();
90       _rw->read(&_buf[0]);
91       _cur=_rw->current_slice();
92     }
93 
value(void)94     const T& value(void) const
95     {
96       return _buf[_count];
97     }
98   };
99 
100   template <class T> class minc_output_iterator
101   {
102     protected:
103       mutable minc_1_writer* _rw;
104       std::vector<T> _buf;
105       std::vector<long> _cur;
106       bool _last;
107       size_t _count;
108     public:
cur(void)109     const std::vector<long>& cur(void) const
110     {
111       return _cur;
112     }
113 
minc_output_iterator(const minc_output_iterator<T> & a)114     minc_output_iterator(const minc_output_iterator<T>& a):_rw(a._rw),_cur(a._cur),_last(a._last),_count(a._count)
115     {
116     }
117 
minc_output_iterator(minc_1_writer & rw)118     minc_output_iterator(minc_1_writer& rw):_rw(&rw),_last(false),_count(0)
119     {
120       _buf.resize(rw.slice_len());
121     }
122 
minc_output_iterator()123     minc_output_iterator():_rw(NULL),_last(false),_count(0)
124     {
125     }
126 
attach(minc_1_writer & rw)127     void attach(minc_1_writer& rw)
128     {
129       _rw=&rw;
130       _last=false;
131       _count=0;
132     }
133 
~minc_output_iterator()134     ~minc_output_iterator()
135     {
136       if(_count && !_last)
137         _rw->write(&_buf[0]);
138     }
139 
next(void)140     bool next(void)
141     {
142       if(_last) return false;
143       _count++;
144       for(int i=_rw->dim_no()-1;i>(_rw->dim_no()-_rw->slice_dimensions()-1);i--)
145       {
146         _cur[i]++;
147         if(_cur[i]<static_cast<long>(_rw->dim(i).length))
148           break;
149         if(i>(_rw->dim_no()-_rw->slice_dimensions()))
150           _cur[i]=0;
151         else
152         {
153           //write slice into minc file
154           _rw->write(&_buf[0]);
155           _count=0;
156           //move to next slice
157           if(i==0) // the case when slice_dimensions==dim_no
158           {
159             _last=true;
160             return false;
161           }
162           if(!_rw->next_slice())
163           {
164             _last=true;
165             break;
166           }
167           _cur=_rw->current_slice();
168           break;
169         }
170       }
171       return !_last;
172     }
173 
last(void)174     bool last(void)
175     {
176       return _last;
177     }
178 
begin(void)179     void begin(void)
180     {
181       _buf.resize(_rw->slice_len());
182       _cur.resize(MAX_VAR_DIMS,0);
183       _count=0;
184       _rw->begin();
185       _cur=_rw->current_slice();
186     }
187 
value(const T & v)188     void value(const T& v)
189     {
190       _buf[_count]=v;
191     }
192   };
193 
194   //! will attempt to laod the whole volume in T Z Y X V order into buffer, file should be prepared (setup_read_XXXX)
load_standard_volume(minc_1_reader & rw,T * volume)195   template<class T> void load_standard_volume(minc_1_reader& rw, T* volume)
196   {
197     std::vector<size_t> strides(MAX_VAR_DIMS,0);
198     size_t str=1;
199     for(size_t i=0;i<5;i++)
200     {
201       if(rw.map_space(i)<0) continue;
202       strides[rw.map_space(i)]=str;
203       str*=rw.ndim(i);
204     }
205 
206     minc_input_iterator<T> in(rw);
207     for(in.begin();!in.last();in.next())
208     {
209       size_t address=0;
210       for(size_t i=0;i<static_cast<size_t>(rw.dim_no());i++)
211         address+=in.cur()[i]*strides[i];
212 
213       volume[address]=in.value();
214     }
215   }
216 
217   //! will attempt to save the whole volume in T Z Y X V order from buffer, file should be prepared (setup_read_XXXX)
save_standard_volume(minc_1_writer & rw,const T * volume)218   template<class T> void save_standard_volume(minc_1_writer& rw, const T* volume)
219   {
220     std::vector<size_t> strides(MAX_VAR_DIMS,0);
221     size_t str=1;
222     for(size_t i=0;i<5;i++)
223     {
224       if(rw.map_space(i)<0) continue;
225       strides[rw.map_space(i)]=str;
226       str*=rw.ndim(i);
227     }
228 
229     minc_output_iterator<T> out(rw);
230     for(out.begin();!out.last();out.next())
231     {
232       size_t address=0;
233       for(size_t i=0;i<static_cast<size_t>(rw.dim_no());i++)
234         address+=out.cur()[i]*strides[i];
235 
236       out.value(volume[address]);
237     }
238   }
239 
240   //! will attempt to load the whole volume in Z Y X T V  order into buffer, file should be prepared (setup_read_XXXX)
load_non_standard_volume(minc_1_reader & rw,T * volume)241   template<class T> void load_non_standard_volume(minc_1_reader& rw, T* volume)
242   {
243     std::vector<size_t> strides(MAX_VAR_DIMS,0);
244     size_t str=1;
245     const size_t dimorder[]={0,4,1,2,3};
246     for(size_t i=0;i<5;i++)
247     {
248       if(rw.map_space(dimorder[i])<0|| !rw.ndim(dimorder[i]) ) continue;
249       strides[rw.map_space(dimorder[i])]=str;
250       str*=rw.ndim(dimorder[i]);
251     }
252 
253     minc_input_iterator<T> in(rw);
254     for(in.begin();!in.last();in.next())
255     {
256       size_t address=0;
257       for(int i=0;i<rw.dim_no();i++)
258         address+=in.cur()[i]*strides[i];
259 
260       volume[address]=in.value();
261     }
262   }
263 
264   //! will attempt to save the whole volume in V T Z Y X order from buffer, file should be prepared (setup_read_XXXX)
save_non_standard_volume(minc_1_writer & rw,const T * volume)265   template<class T> void save_non_standard_volume(minc_1_writer& rw, const T* volume)
266   {
267     std::vector<size_t> strides(MAX_VAR_DIMS,0);
268     size_t str=1;
269     const size_t dimorder[]={0,4,1,2,3};
270     for(size_t i=0;i<5;i++)
271     {
272       if(rw.map_space(dimorder[i])<0 || !rw.ndim(dimorder[i]) ) continue;
273       strides[rw.map_space(dimorder[i])]=str;
274       str*=rw.ndim(dimorder[i]);
275     }
276     minc_output_iterator<T> out(rw);
277     for(out.begin();!out.last();out.next())
278     {
279       size_t address=0;
280       for(int i=0;i<rw.dim_no();i++)
281         address+=out.cur()[i]*strides[i];
282 
283       out.value(volume[address]);
284     }
285   }
286 
287 
288 };//minc
289 
290 #endif //__MINC_1_SIMPLE_H__
291