ForEachQuaternaryVoxelFunction.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * ATTENTION: This source file has been automatically generated using the code
20  * generator mirtkForEachVoxelFunction.py! This generator is
21  * invoked during CMake configuration of the build system when this
22  * source file is missing from the project.
23  *
24  * DO NOT modify this file manually. Instead, modify the code
25  * generator, remove any existing mirtkForEach*VoxelFunction.h
26  * header file from the include/ directory and then re-run CMake.
27  * This will invoke the code generator to re-generate the source files.
28  */
29 
30 #ifndef MIRTK_ForEachQuaternaryVoxelFunction_H
31 #define MIRTK_ForEachQuaternaryVoxelFunction_H
32 
33 #include "mirtk/Stream.h"
34 #include "mirtk/VoxelFunction.h"
35 
36 
37 namespace mirtk {
38 
39 
40 inline void _foreachquaternaryvoxelfunction_must_not_be_reduction()
41 {
42  cerr << "(Parallel)ForEachVoxel(If): Voxel reductions must be passed by reference!"
43  " Pass voxel functor object(s) as last argument(s) instead of first." << endl;
44  exit(1);
45 }
46 
47 
48 // =============================================================================
49 // 4 const images
50 // =============================================================================
51 
52 // -----------------------------------------------------------------------------
53 /**
54  * ForEachVoxel body for voxel function of 4 const images
55  */
56 template <class T1, class T2, class T3, class T4, class VoxelFunc>
58 {
59  const GenericImage<T1> &im1;
60  const GenericImage<T2> &im2;
61  const GenericImage<T3> &im3;
62  const GenericImage<T4> &im4;
63 
64  /// Constructor
66  const GenericImage<T2> &im2,
67  const GenericImage<T3> &im3,
68  const GenericImage<T4> &im4,
69  VoxelFunc &vf)
70  :
71  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
72  {}
73 
74  /// Copy constructor
76  :
77  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
78  {}
79 
80  /// Split constructor
82  :
83  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
84  {}
85 
86  /// Process entire image
87  void operator ()(const ImageAttributes &attr) const
88  {
89  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
90  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
91  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
92  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
93 
94  const int T = (attr._dt ? attr._t : 1);
95 
96  for (int l = 0; l < T; ++l)
97  for (int k = 0; k < attr._z; ++k)
98  for (int j = 0; j < attr._y; ++j)
99  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
100  // const_cast such that voxel functions need only implement
101  // non-const operator() which is required for parallel_reduce
102  const_cast<QuaternaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4);
103  }
104  }
105 
106  /// Process image region using linear index
107  void operator ()(const blocked_range<int> &re) const
108  {
109  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
110  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
111  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
112  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
113 
114  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
115  // const_cast such that voxel functions need only implement
116  // non-const operator() which is required for parallel_reduce
117  const_cast<QuaternaryForEachVoxelBody_Const *>(this)->_VoxelFunc(im4, idx, p1, p2, p3, p4);
118  }
119  }
120 
121  /// Process 2D image region
122  void operator ()(const blocked_range2d<int> &re) const
123  {
124  const int bi = re.cols().begin();
125  const int bj = re.rows().begin();
126  const int ei = re.cols().end();
127  const int ej = re.rows().end();
128 
129  const int s1 = im4.GetX() - (ei - bi);
130 
131  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
132  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
133  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
134  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
135 
136  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
137  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
138  // const_cast such that voxel functions need only implement
139  // non-const operator() which is required for parallel_reduce
140  const_cast<QuaternaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
141  }
142  }
143 
144  /// Process 3D image region
145  void operator ()(const blocked_range3d<int> &re) const
146  {
147  const int bi = re.cols ().begin();
148  const int bj = re.rows ().begin();
149  const int bk = re.pages().begin();
150  const int ei = re.cols ().end();
151  const int ej = re.rows ().end();
152  const int ek = re.pages().end();
153 
154  const int s1 = im4.GetX() - (ei - bi);
155  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
156 
157  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
158  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
159  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
160  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
161 
162  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
163  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
164  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
165  // const_cast such that voxel functions need only implement
166  // non-const operator() which is required for parallel_reduce
167  const_cast<QuaternaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4);
168  }
169  }
170 };
171 
172 // -----------------------------------------------------------------------------
173 /**
174  * ForEachVoxel body for inside and outside unary voxel function of 4 const images
175  */
176 template <class T1, class T2, class T3, class T4,
177  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
178  class Domain = ForEachVoxelDomain::Foreground>
179 struct QuaternaryForEachVoxelIfBody_Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
180 {
181  const GenericImage<T1> &im1;
182  const GenericImage<T2> &im2;
183  const GenericImage<T3> &im3;
184  const GenericImage<T4> &im4;
185 
186  /// Constructor
188  const GenericImage<T2> &im2,
189  const GenericImage<T3> &im3,
190  const GenericImage<T4> &im4,
191  VoxelFunc &vf, OutsideFunc &of)
192  :
193  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
194  {}
195 
196  /// Copy constructor
198  :
199  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
200  {}
201 
202  /// Split constructor
204  :
205  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
206  {}
207 
208  /// Process entire image
209  void operator ()(const ImageAttributes &attr) const
210  {
211  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
212  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
213  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
214  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
215 
216  const int T = (attr._dt ? attr._t : 1);
217 
218  for (int l = 0; l < T; ++l)
219  for (int k = 0; k < attr._z; ++k)
220  for (int j = 0; j < attr._y; ++j)
221  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
222  if (Domain::IsInside(im4, i, j, k, l, p4)) {
223  // const_cast such that voxel functions need only implement
224  // non-const operator() which is required for parallel_reduce
225  const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4);
226  } else const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4);
227  }
228  }
229 
230  /// Process image region using linear index
231  void operator ()(const blocked_range<int> &re) const
232  {
233  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
234  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
235  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
236  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
237 
238  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
239  if (Domain::IsInside(im4, idx, p4)) {
240  // const_cast such that voxel functions need only implement
241  // non-const operator() which is required for parallel_reduce
242  const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (im4, idx, p1, p2, p3, p4);
243  } else const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(im4, idx, p1, p2, p3, p4);
244  }
245  }
246 
247  /// Process 2D image region
248  void operator ()(const blocked_range2d<int> &re) const
249  {
250  const int bi = re.cols().begin();
251  const int bj = re.rows().begin();
252  const int ei = re.cols().end();
253  const int ej = re.rows().end();
254 
255  const int s1 = im4.GetX() - (ei - bi);
256 
257  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
258  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
259  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
260  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
261 
262  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
263  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
264  if (Domain::IsInside(im4, i, j, this->_k, this->_l, p4)) {
265  // const_cast such that voxel functions need only implement
266  // non-const operator() which is required for parallel_reduce
267  const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4);
268  } else const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
269  }
270  }
271 
272  /// Process 3D image region
273  void operator ()(const blocked_range3d<int> &re) const
274  {
275  const int bi = re.cols ().begin();
276  const int bj = re.rows ().begin();
277  const int bk = re.pages().begin();
278  const int ei = re.cols ().end();
279  const int ej = re.rows ().end();
280  const int ek = re.pages().end();
281 
282  const int s1 = im4.GetX() - (ei - bi);
283  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
284 
285  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
286  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
287  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
288  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
289 
290  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
291  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
292  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
293  if (Domain::IsInside(im4, i, j, k, this->_l, p4)) {
294  // const_cast such that voxel functions need only implement
295  // non-const operator() which is required for parallel_reduce
296  const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4);
297  } else const_cast<QuaternaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4);
298  }
299  }
300 };
301 
302 // -----------------------------------------------------------------------------
303 // ForEachVoxel
304 // -----------------------------------------------------------------------------
305 
306 //
307 // Image arguments by pointer
308 //
309 
310 // -----------------------------------------------------------------------------
311 template <class T1, class T2, class T3, class T4, class VoxelFunc>
312 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
313 {
314  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
316  body(re);
317  vf.join(body._VoxelFunc);
318 }
319 
320 // -----------------------------------------------------------------------------
321 template <class T1, class T2, class T3, class T4, class VoxelFunc>
322 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
323 {
324  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
325  ForEachScalar(*im1, *im2, *im3, *im4, vf);
326 }
327 
328 // -----------------------------------------------------------------------------
329 template <class T1, class T2, class T3, class T4, class VoxelFunc>
330 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
331 {
332  if (im4->GetTSize()) {
333  ForEachScalar(*im1, *im2, *im3, *im4, vf);
334  } else {
335  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
336  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
337  body(re);
338  vf.join(body._VoxelFunc);
339  }
340 }
341 
342 // -----------------------------------------------------------------------------
343 template <class T1, class T2, class T3, class T4, class VoxelFunc>
344 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
345 {
346  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
347  ForEachVoxel(*im1, *im2, *im3, *im4, vf);
348 }
349 
350 // -----------------------------------------------------------------------------
351 template <class T1, class T2, class T3, class T4, class VoxelFunc>
352 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
353 {
354  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
355  body(attr);
356  vf.join(body._VoxelFunc);
357 }
358 
359 // -----------------------------------------------------------------------------
360 template <class T1, class T2, class T3, class T4, class VoxelFunc>
361 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
362 {
363  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
364  ForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
365 }
366 
367 // -----------------------------------------------------------------------------
368 template <class T1, class T2, class T3, class T4, class VoxelFunc>
369 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
370 {
371  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
372  body(re);
373  vf.join(body._VoxelFunc);
374 }
375 
376 // -----------------------------------------------------------------------------
377 template <class T1, class T2, class T3, class T4, class VoxelFunc>
378 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
379 {
380  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
381  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
382 }
383 
384 // -----------------------------------------------------------------------------
385 template <class T1, class T2, class T3, class T4, class VoxelFunc>
386 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
387 {
388  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
389  body(re);
390  vf.join(body._VoxelFunc);
391 }
392 
393 // -----------------------------------------------------------------------------
394 template <class T1, class T2, class T3, class T4, class VoxelFunc>
395 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
396 {
397  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
398  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
399 }
400 
401 // -----------------------------------------------------------------------------
402 template <class T1, class T2, class T3, class T4, class VoxelFunc>
403 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
404 {
405  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
406  body(re);
407  vf.join(body._VoxelFunc);
408 }
409 
410 // -----------------------------------------------------------------------------
411 template <class T1, class T2, class T3, class T4, class VoxelFunc>
412 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
413 {
414  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
415  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
416 }
417 
418 //
419 // Image arguments by reference
420 //
421 
422 // -----------------------------------------------------------------------------
423 template <class T1, class T2, class T3, class T4, class VoxelFunc>
424 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
425 {
428  body(re);
429  vf.join(body._VoxelFunc);
430 }
431 
432 // -----------------------------------------------------------------------------
433 template <class T1, class T2, class T3, class T4, class VoxelFunc>
434 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
435 {
436  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
437  ForEachScalar(im1, im2, im3, im4, vf);
438 }
439 
440 // -----------------------------------------------------------------------------
441 template <class T1, class T2, class T3, class T4, class VoxelFunc>
442 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
443 {
444  if (im4.GetTSize()) {
445  ForEachScalar(im1, im2, im3, im4, vf);
446  } else {
448  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
449  body(re);
450  vf.join(body._VoxelFunc);
451  }
452 }
453 
454 // -----------------------------------------------------------------------------
455 template <class T1, class T2, class T3, class T4, class VoxelFunc>
456 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
457 {
458  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
459  ForEachVoxel(im1, im2, im3, im4, vf);
460 }
461 
462 // -----------------------------------------------------------------------------
463 template <class T1, class T2, class T3, class T4, class VoxelFunc>
464 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
465 {
467  body(attr);
468  vf.join(body._VoxelFunc);
469 }
470 
471 // -----------------------------------------------------------------------------
472 template <class T1, class T2, class T3, class T4, class VoxelFunc>
473 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
474 {
475  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
476  ForEachVoxel(attr, im1, im2, im3, im4, vf);
477 }
478 
479 // -----------------------------------------------------------------------------
480 template <class T1, class T2, class T3, class T4, class VoxelFunc>
481 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
482 {
484  body(re);
485  vf.join(body._VoxelFunc);
486 }
487 
488 // -----------------------------------------------------------------------------
489 template <class T1, class T2, class T3, class T4, class VoxelFunc>
490 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
491 {
492  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
493  ForEachVoxel(re, im1, im2, im3, im4, vf);
494 }
495 
496 // -----------------------------------------------------------------------------
497 template <class T1, class T2, class T3, class T4, class VoxelFunc>
498 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
499 {
501  body(re);
502  vf.join(body._VoxelFunc);
503 }
504 
505 // -----------------------------------------------------------------------------
506 template <class T1, class T2, class T3, class T4, class VoxelFunc>
507 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
508 {
509  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
510  ForEachVoxel(re, im1, im2, im3, im4, vf);
511 }
512 
513 // -----------------------------------------------------------------------------
514 template <class T1, class T2, class T3, class T4, class VoxelFunc>
515 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
516 {
518  body(re);
519  vf.join(body._VoxelFunc);
520 }
521 
522 // -----------------------------------------------------------------------------
523 template <class T1, class T2, class T3, class T4, class VoxelFunc>
524 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
525 {
526  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
527  ForEachVoxel(re, im1, im2, im3, im4, vf);
528 }
529 
530 // -----------------------------------------------------------------------------
531 // ForEachVoxelIf
532 // -----------------------------------------------------------------------------
533 
534 //
535 // Image arguments by pointer
536 //
537 
538 // -----------------------------------------------------------------------------
539 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
540 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
541 {
544  body(re);
545  vf.join(body._VoxelFunc);
546  of.join(body._OutsideFunc);
547 }
548 
549 // -----------------------------------------------------------------------------
550 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
551 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
552 {
553  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
554  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
555 }
556 
557 // -----------------------------------------------------------------------------
558 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
559 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
560 {
562  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
563 }
564 
565 // -----------------------------------------------------------------------------
566 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
567 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
568 {
569  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
570  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
571 }
572 
573 // -----------------------------------------------------------------------------
574 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
575 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
576 {
577  if (im4->GetTSize()) {
578  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
579  } else {
581  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
582  body(re);
583  vf.join(body._VoxelFunc);
584  of.join(body._OutsideFunc);
585  }
586 }
587 
588 // -----------------------------------------------------------------------------
589 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
590 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
591 {
592  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
593  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
594 }
595 
596 // -----------------------------------------------------------------------------
597 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
598 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
599 {
601  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
602 }
603 
604 // -----------------------------------------------------------------------------
605 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
606 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
607 {
608  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
609  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
610 }
611 
612 // -----------------------------------------------------------------------------
613 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
614 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
615 {
617  body(attr);
618  vf.join(body._VoxelFunc);
619  of.join(body._OutsideFunc);
620 }
621 
622 // -----------------------------------------------------------------------------
623 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
624 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
625 {
626  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
627  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
628 }
629 
630 // -----------------------------------------------------------------------------
631 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
632 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
633 {
635  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
636 }
637 
638 // -----------------------------------------------------------------------------
639 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
640 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
641 {
642  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
643  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
644 }
645 
646 // -----------------------------------------------------------------------------
647 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
648 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
649 {
651  body(re);
652  vf.join(body._VoxelFunc);
653  of.join(body._OutsideFunc);
654 }
655 
656 // -----------------------------------------------------------------------------
657 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
658 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
659 {
660  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
661  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
662 }
663 
664 // -----------------------------------------------------------------------------
665 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
666 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
667 {
669  body(re);
670  vf.join(body._VoxelFunc);
671  of.join(body._OutsideFunc);
672 }
673 
674 // -----------------------------------------------------------------------------
675 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
676 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
677 {
678  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
679  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
680 }
681 
682 // -----------------------------------------------------------------------------
683 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
684 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
685 {
687  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
688 }
689 
690 // -----------------------------------------------------------------------------
691 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
692 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
693 {
694  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
695  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
696 }
697 
698 // -----------------------------------------------------------------------------
699 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
700 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
701 {
703  body(re);
704  vf.join(body._VoxelFunc);
705  of.join(body._OutsideFunc);
706 }
707 
708 // -----------------------------------------------------------------------------
709 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
710 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
711 {
712  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
713  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
714 }
715 
716 // -----------------------------------------------------------------------------
717 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
718 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
719 {
721  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
722 }
723 
724 // -----------------------------------------------------------------------------
725 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
726 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
727 {
728  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
729  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
730 }
731 
732 //
733 // Image arguments by reference
734 //
735 
736 // -----------------------------------------------------------------------------
737 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
738 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
739 {
742  body(re);
743  vf.join(body._VoxelFunc);
744  of.join(body._OutsideFunc);
745 }
746 
747 // -----------------------------------------------------------------------------
748 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
749 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
750 {
751  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
752  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
753 }
754 
755 // -----------------------------------------------------------------------------
756 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
757 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
758 {
760  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
761 }
762 
763 // -----------------------------------------------------------------------------
764 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
765 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
766 {
767  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
768  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
769 }
770 
771 // -----------------------------------------------------------------------------
772 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
773 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
774 {
775  if (im4.GetTSize()) {
776  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
777  } else {
779  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
780  body(re);
781  vf.join(body._VoxelFunc);
782  of.join(body._OutsideFunc);
783  }
784 }
785 
786 // -----------------------------------------------------------------------------
787 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
788 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
789 {
790  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
791  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
792 }
793 
794 // -----------------------------------------------------------------------------
795 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
796 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
797 {
799  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
800 }
801 
802 // -----------------------------------------------------------------------------
803 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
804 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
805 {
806  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
807  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
808 }
809 
810 // -----------------------------------------------------------------------------
811 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
812 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
813 {
815  body(attr);
816  vf.join(body._VoxelFunc);
817  of.join(body._OutsideFunc);
818 }
819 
820 // -----------------------------------------------------------------------------
821 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
822 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
823 {
824  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
825  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
826 }
827 
828 // -----------------------------------------------------------------------------
829 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
830 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
831 {
833  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
834 }
835 
836 // -----------------------------------------------------------------------------
837 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
838 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
839 {
840  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
841  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
842 }
843 
844 // -----------------------------------------------------------------------------
845 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
846 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
847 {
849  body(re);
850  vf.join(body._VoxelFunc);
851  of.join(body._OutsideFunc);
852 }
853 
854 // -----------------------------------------------------------------------------
855 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
856 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
857 {
858  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
859  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
860 }
861 
862 // -----------------------------------------------------------------------------
863 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
864 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
865 {
867  body(re);
868  vf.join(body._VoxelFunc);
869  of.join(body._OutsideFunc);
870 }
871 
872 // -----------------------------------------------------------------------------
873 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
874 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
875 {
876  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
877  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
878 }
879 
880 // -----------------------------------------------------------------------------
881 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
882 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
883 {
885  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
886 }
887 
888 // -----------------------------------------------------------------------------
889 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
890 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
891 {
892  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
893  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
894 }
895 
896 // -----------------------------------------------------------------------------
897 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
898 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
899 {
901  body(re);
902  vf.join(body._VoxelFunc);
903  of.join(body._OutsideFunc);
904 }
905 
906 // -----------------------------------------------------------------------------
907 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
908 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
909 {
910  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
911  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
912 }
913 
914 // -----------------------------------------------------------------------------
915 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
916 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
917 {
919  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
920 }
921 
922 // -----------------------------------------------------------------------------
923 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
924 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
925 {
926  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
927  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
928 }
929 
930 // -----------------------------------------------------------------------------
931 // ParallelForEachVoxel
932 // -----------------------------------------------------------------------------
933 
934 //
935 // Image arguments by pointer
936 //
937 
938 // -----------------------------------------------------------------------------
939 template <class T1, class T2, class T3, class T4, class VoxelFunc>
940 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
941 {
942  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
944  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
945  else parallel_for (re, body);
946 }
947 
948 // -----------------------------------------------------------------------------
949 template <class T1, class T2, class T3, class T4, class VoxelFunc>
950 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
951 {
952  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
953  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
954 }
955 
956 // -----------------------------------------------------------------------------
957 template <class T1, class T2, class T3, class T4, class VoxelFunc>
958 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
959 {
960  if (im4->GetTSize()) {
961  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
962  } else {
963  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
964  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
965  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
966  else parallel_for (re, body);
967  }
968 }
969 
970 // -----------------------------------------------------------------------------
971 template <class T1, class T2, class T3, class T4, class VoxelFunc>
972 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
973 {
974  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
975  ParallelForEachVoxel(*im1, *im2, *im3, *im4, vf);
976 }
977 
978 // -----------------------------------------------------------------------------
979 template <class T1, class T2, class T3, class T4, class VoxelFunc>
980 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
981 {
982  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
983  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
984  if (VoxelFunc::IsReduction()) {
985  if (attr._dt) {
986  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
987  } else {
988  parallel_reduce(re, body);
989  }
990  vf.join(body._VoxelFunc);
991  } else {
992  if (attr._dt) {
993  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
994  } else {
995  parallel_for(re, body);
996  }
997  }
998 }
999 
1000 // -----------------------------------------------------------------------------
1001 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1002 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1003 {
1004  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1005  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
1006 }
1007 
1008 // -----------------------------------------------------------------------------
1009 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1010 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1011 {
1012  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
1013  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1014  else parallel_for (re, body);
1015 }
1016 
1017 // -----------------------------------------------------------------------------
1018 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1019 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1020 {
1021  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1022  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
1023 }
1024 
1025 // -----------------------------------------------------------------------------
1026 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1027 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1028 {
1029  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
1030  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1031  else parallel_for (re, body);
1032 }
1033 
1034 // -----------------------------------------------------------------------------
1035 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1036 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1037 {
1038  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1039  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
1040 }
1041 
1042 // -----------------------------------------------------------------------------
1043 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1044 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1045 {
1046  QuaternaryForEachVoxelBody_Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
1047  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1048  else parallel_for (re, body);
1049 }
1050 
1051 // -----------------------------------------------------------------------------
1052 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1053 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1054 {
1055  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1056  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
1057 }
1058 
1059 //
1060 // Image arguments by reference
1061 //
1062 
1063 // -----------------------------------------------------------------------------
1064 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1065 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1066 {
1069  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1070  else parallel_for (re, body);
1071 }
1072 
1073 // -----------------------------------------------------------------------------
1074 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1075 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1076 {
1077  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1078  ParallelForEachScalar(im1, im2, im3, im4, vf);
1079 }
1080 
1081 // -----------------------------------------------------------------------------
1082 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1083 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1084 {
1085  if (im4.GetTSize()) {
1086  ParallelForEachScalar(im1, im2, im3, im4, vf);
1087  } else {
1089  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
1090  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1091  else parallel_for (re, body);
1092  }
1093 }
1094 
1095 // -----------------------------------------------------------------------------
1096 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1097 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1098 {
1099  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1100  ParallelForEachVoxel(im1, im2, im3, im4, vf);
1101 }
1102 
1103 // -----------------------------------------------------------------------------
1104 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1105 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1106 {
1108  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1109  if (VoxelFunc::IsReduction()) {
1110  if (attr._dt) {
1111  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1112  } else {
1113  parallel_reduce(re, body);
1114  }
1115  vf.join(body._VoxelFunc);
1116  } else {
1117  if (attr._dt) {
1118  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1119  } else {
1120  parallel_for(re, body);
1121  }
1122  }
1123 }
1124 
1125 // -----------------------------------------------------------------------------
1126 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1127 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1128 {
1129  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1130  ParallelForEachVoxel(attr, im1, im2, im3, im4, vf);
1131 }
1132 
1133 // -----------------------------------------------------------------------------
1134 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1135 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1136 {
1138  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1139  else parallel_for (re, body);
1140 }
1141 
1142 // -----------------------------------------------------------------------------
1143 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1144 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1145 {
1146  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1147  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
1148 }
1149 
1150 // -----------------------------------------------------------------------------
1151 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1152 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1153 {
1155  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1156  else parallel_for (re, body);
1157 }
1158 
1159 // -----------------------------------------------------------------------------
1160 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1161 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1162 {
1163  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1164  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
1165 }
1166 
1167 // -----------------------------------------------------------------------------
1168 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1169 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1170 {
1172  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1173  else parallel_for (re, body);
1174 }
1175 
1176 // -----------------------------------------------------------------------------
1177 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1178 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1179 {
1180  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1181  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
1182 }
1183 
1184 // -----------------------------------------------------------------------------
1185 // ParallelForEachVoxelIf
1186 // -----------------------------------------------------------------------------
1187 
1188 //
1189 // Image arguments by pointer
1190 //
1191 
1192 // -----------------------------------------------------------------------------
1193 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1194 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
1195 {
1197  blocked_range<int> re(0, im4->GetNumberOfVoxels());
1198  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1199  parallel_reduce(re, body);
1200  vf.join(body._VoxelFunc);
1201  of.join(body._OutsideFunc);
1202  } else {
1203  parallel_for(re, body);
1204  }
1205 }
1206 
1207 // -----------------------------------------------------------------------------
1208 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1209 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1210 {
1211  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1212  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
1213 }
1214 
1215 // -----------------------------------------------------------------------------
1216 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1217 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1218 {
1220  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
1221 }
1222 
1223 // -----------------------------------------------------------------------------
1224 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1225 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1226 {
1227  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1228  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
1229 }
1230 
1231 // -----------------------------------------------------------------------------
1232 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1233 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
1234 {
1235  if (im4->GetTSize()) {
1236  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
1237  } else {
1239  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
1240  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1241  parallel_reduce(re, body);
1242  vf.join(body._VoxelFunc);
1243  of.join(body._OutsideFunc);
1244  } else {
1245  parallel_for(re, body);
1246  }
1247  }
1248 }
1249 
1250 // -----------------------------------------------------------------------------
1251 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1252 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1253 {
1254  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1255  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
1256 }
1257 
1258 // -----------------------------------------------------------------------------
1259 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1260 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1261 {
1263  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
1264 }
1265 
1266 // -----------------------------------------------------------------------------
1267 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1268 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1269 {
1270  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1271  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
1272 }
1273 
1274 // -----------------------------------------------------------------------------
1275 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1276 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
1277 {
1279  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1280  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1281  if (attr._dt) {
1282  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1283  } else {
1284  parallel_reduce(re, body);
1285  }
1286  vf.join(body._VoxelFunc);
1287  of.join(body._OutsideFunc);
1288  } else {
1289  if (attr._dt) {
1290  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1291  } else {
1292  parallel_for(re, body);
1293  }
1294  }
1295 }
1296 
1297 // -----------------------------------------------------------------------------
1298 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1299 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1300 {
1301  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1302  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
1303 }
1304 
1305 // -----------------------------------------------------------------------------
1306 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1307 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1308 {
1310  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
1311 }
1312 
1313 // -----------------------------------------------------------------------------
1314 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1315 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1316 {
1317  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1318  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
1319 }
1320 
1321 // -----------------------------------------------------------------------------
1322 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1323 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
1324 {
1326  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1327  parallel_reduce(re, body);
1328  vf.join(body._VoxelFunc);
1329  of.join(body._OutsideFunc);
1330  } else {
1331  parallel_for(re, body);
1332  }
1333 }
1334 
1335 // -----------------------------------------------------------------------------
1336 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1337 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1338 {
1339  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1340  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
1341 }
1342 
1343 // -----------------------------------------------------------------------------
1344 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1345 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1346 {
1348  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
1349 }
1350 
1351 // -----------------------------------------------------------------------------
1352 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1353 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1354 {
1355  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1356  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
1357 }
1358 
1359 // -----------------------------------------------------------------------------
1360 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1361 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
1362 {
1364  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1365  parallel_reduce(re, body);
1366  vf.join(body._VoxelFunc);
1367  of.join(body._OutsideFunc);
1368  } else {
1369  parallel_for(re, body);
1370  }
1371 }
1372 
1373 // -----------------------------------------------------------------------------
1374 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1375 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1376 {
1377  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1378  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
1379 }
1380 
1381 // -----------------------------------------------------------------------------
1382 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1383 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1384 {
1386  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
1387 }
1388 
1389 // -----------------------------------------------------------------------------
1390 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1391 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1392 {
1393  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1394  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
1395 }
1396 
1397 // -----------------------------------------------------------------------------
1398 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1399 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
1400 {
1402  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1403  parallel_reduce(re, body);
1404  vf.join(body._VoxelFunc);
1405  of.join(body._OutsideFunc);
1406  } else {
1407  parallel_for(re, body);
1408  }
1409 }
1410 
1411 // -----------------------------------------------------------------------------
1412 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1413 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1414 {
1415  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1416  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
1417 }
1418 
1419 // -----------------------------------------------------------------------------
1420 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1421 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, VoxelFunc &vf)
1422 {
1424  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
1425 }
1426 
1427 // -----------------------------------------------------------------------------
1428 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1429 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4)
1430 {
1431  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1432  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
1433 }
1434 
1435 //
1436 // Image arguments by reference
1437 //
1438 
1439 // -----------------------------------------------------------------------------
1440 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1441 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
1442 {
1445  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1446  parallel_reduce(re, body);
1447  vf.join(body._VoxelFunc);
1448  of.join(body._OutsideFunc);
1449  } else {
1450  parallel_for(re, body);
1451  }
1452 }
1453 
1454 // -----------------------------------------------------------------------------
1455 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1456 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1457 {
1458  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1459  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
1460 }
1461 
1462 // -----------------------------------------------------------------------------
1463 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1464 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1465 {
1467  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
1468 }
1469 
1470 // -----------------------------------------------------------------------------
1471 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1472 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1473 {
1474  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1475  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
1476 }
1477 
1478 // -----------------------------------------------------------------------------
1479 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1480 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
1481 {
1482  if (im4.GetTSize()) {
1483  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
1484  } else {
1486  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
1487  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1488  parallel_reduce(re, body);
1489  vf.join(body._VoxelFunc);
1490  of.join(body._OutsideFunc);
1491  } else {
1492  parallel_for(re, body);
1493  }
1494  }
1495 }
1496 
1497 // -----------------------------------------------------------------------------
1498 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1499 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1500 {
1501  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1502  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
1503 }
1504 
1505 // -----------------------------------------------------------------------------
1506 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1507 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1508 {
1510  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
1511 }
1512 
1513 // -----------------------------------------------------------------------------
1514 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1515 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1516 {
1517  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1518  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
1519 }
1520 
1521 // -----------------------------------------------------------------------------
1522 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1523 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
1524 {
1526  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1527  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1528  if (attr._dt) {
1529  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1530  } else {
1531  parallel_reduce(re, body);
1532  }
1533  vf.join(body._VoxelFunc);
1534  of.join(body._OutsideFunc);
1535  } else {
1536  if (attr._dt) {
1537  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1538  } else {
1539  parallel_for(re, body);
1540  }
1541  }
1542 }
1543 
1544 // -----------------------------------------------------------------------------
1545 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1546 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1547 {
1548  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1549  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
1550 }
1551 
1552 // -----------------------------------------------------------------------------
1553 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1554 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1555 {
1557  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
1558 }
1559 
1560 // -----------------------------------------------------------------------------
1561 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1562 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1563 {
1564  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1565  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
1566 }
1567 
1568 // -----------------------------------------------------------------------------
1569 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1570 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
1571 {
1573  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1574  parallel_reduce(re, body);
1575  vf.join(body._VoxelFunc);
1576  of.join(body._OutsideFunc);
1577  } else {
1578  parallel_for(re, body);
1579  }
1580 }
1581 
1582 // -----------------------------------------------------------------------------
1583 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1584 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1585 {
1586  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1587  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
1588 }
1589 
1590 // -----------------------------------------------------------------------------
1591 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1592 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1593 {
1595  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
1596 }
1597 
1598 // -----------------------------------------------------------------------------
1599 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1600 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1601 {
1602  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1603  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
1604 }
1605 
1606 // -----------------------------------------------------------------------------
1607 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1608 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
1609 {
1611  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1612  parallel_reduce(re, body);
1613  vf.join(body._VoxelFunc);
1614  of.join(body._OutsideFunc);
1615  } else {
1616  parallel_for(re, body);
1617  }
1618 }
1619 
1620 // -----------------------------------------------------------------------------
1621 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1622 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1623 {
1624  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1625  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
1626 }
1627 
1628 // -----------------------------------------------------------------------------
1629 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1630 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1631 {
1633  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
1634 }
1635 
1636 // -----------------------------------------------------------------------------
1637 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1638 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1639 {
1640  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1641  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
1642 }
1643 
1644 // -----------------------------------------------------------------------------
1645 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1646 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
1647 {
1649  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1650  parallel_reduce(re, body);
1651  vf.join(body._VoxelFunc);
1652  of.join(body._OutsideFunc);
1653  } else {
1654  parallel_for(re, body);
1655  }
1656 }
1657 
1658 // -----------------------------------------------------------------------------
1659 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
1660 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1661 {
1662  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1663  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
1664 }
1665 
1666 // -----------------------------------------------------------------------------
1667 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1668 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, VoxelFunc &vf)
1669 {
1671  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
1672 }
1673 
1674 // -----------------------------------------------------------------------------
1675 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
1676 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4)
1677 {
1678  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1679  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
1680 }
1681 
1682 // =============================================================================
1683 // 3 const, 1 non-const images
1684 // =============================================================================
1685 
1686 // -----------------------------------------------------------------------------
1687 /**
1688  * ForEachVoxel body for voxel function of 3 const, 1 non-const images
1689  */
1690 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1692 {
1693  const GenericImage<T1> &im1;
1694  const GenericImage<T2> &im2;
1695  const GenericImage<T3> &im3;
1696  GenericImage<T4> &im4;
1697 
1698  /// Constructor
1700  const GenericImage<T2> &im2,
1701  const GenericImage<T3> &im3,
1702  GenericImage<T4> &im4,
1703  VoxelFunc &vf)
1704  :
1705  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
1706  {}
1707 
1708  /// Copy constructor
1710  :
1711  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
1712  {}
1713 
1714  /// Split constructor
1716  :
1717  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
1718  {}
1719 
1720  /// Process entire image
1721  void operator ()(const ImageAttributes &attr) const
1722  {
1723  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1724  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1725  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
1726  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
1727 
1728  const int T = (attr._dt ? attr._t : 1);
1729 
1730  for (int l = 0; l < T; ++l)
1731  for (int k = 0; k < attr._z; ++k)
1732  for (int j = 0; j < attr._y; ++j)
1733  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
1734  // const_cast such that voxel functions need only implement
1735  // non-const operator() which is required for parallel_reduce
1736  const_cast<QuaternaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4);
1737  }
1738  }
1739 
1740  /// Process image region using linear index
1741  void operator ()(const blocked_range<int> &re) const
1742  {
1743  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1744  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1745  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
1746  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
1747 
1748  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
1749  // const_cast such that voxel functions need only implement
1750  // non-const operator() which is required for parallel_reduce
1751  const_cast<QuaternaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(im4, idx, p1, p2, p3, p4);
1752  }
1753  }
1754 
1755  /// Process 2D image region
1756  void operator ()(const blocked_range2d<int> &re) const
1757  {
1758  const int bi = re.cols().begin();
1759  const int bj = re.rows().begin();
1760  const int ei = re.cols().end();
1761  const int ej = re.rows().end();
1762 
1763  const int s1 = im4.GetX() - (ei - bi);
1764 
1765  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1766  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1767  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1768  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1769 
1770  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
1771  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
1772  // const_cast such that voxel functions need only implement
1773  // non-const operator() which is required for parallel_reduce
1774  const_cast<QuaternaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
1775  }
1776  }
1777 
1778  /// Process 3D image region
1779  void operator ()(const blocked_range3d<int> &re) const
1780  {
1781  const int bi = re.cols ().begin();
1782  const int bj = re.rows ().begin();
1783  const int bk = re.pages().begin();
1784  const int ei = re.cols ().end();
1785  const int ej = re.rows ().end();
1786  const int ek = re.pages().end();
1787 
1788  const int s1 = im4.GetX() - (ei - bi);
1789  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
1790 
1791  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1792  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1793  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
1794  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
1795 
1796  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
1797  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
1798  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
1799  // const_cast such that voxel functions need only implement
1800  // non-const operator() which is required for parallel_reduce
1801  const_cast<QuaternaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4);
1802  }
1803  }
1804 };
1805 
1806 // -----------------------------------------------------------------------------
1807 /**
1808  * ForEachVoxel body for inside and outside unary voxel function of 3 const, 1 non-const images
1809  */
1810 template <class T1, class T2, class T3, class T4,
1811  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
1812  class Domain = ForEachVoxelDomain::Foreground>
1813 struct QuaternaryForEachVoxelIfBody_3Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
1814 {
1815  const GenericImage<T1> &im1;
1816  const GenericImage<T2> &im2;
1817  const GenericImage<T3> &im3;
1818  GenericImage<T4> &im4;
1819 
1820  /// Constructor
1822  const GenericImage<T2> &im2,
1823  const GenericImage<T3> &im3,
1824  GenericImage<T4> &im4,
1825  VoxelFunc &vf, OutsideFunc &of)
1826  :
1827  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
1828  {}
1829 
1830  /// Copy constructor
1832  :
1833  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
1834  {}
1835 
1836  /// Split constructor
1838  :
1839  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
1840  {}
1841 
1842  /// Process entire image
1843  void operator ()(const ImageAttributes &attr) const
1844  {
1845  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1846  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1847  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
1848  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
1849 
1850  const int T = (attr._dt ? attr._t : 1);
1851 
1852  for (int l = 0; l < T; ++l)
1853  for (int k = 0; k < attr._z; ++k)
1854  for (int j = 0; j < attr._y; ++j)
1855  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
1856  if (Domain::IsInside(im4, i, j, k, l, p4)) {
1857  // const_cast such that voxel functions need only implement
1858  // non-const operator() which is required for parallel_reduce
1859  const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4);
1860  } else const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4);
1861  }
1862  }
1863 
1864  /// Process image region using linear index
1865  void operator ()(const blocked_range<int> &re) const
1866  {
1867  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1868  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1869  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
1870  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
1871 
1872  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
1873  if (Domain::IsInside(im4, idx, p4)) {
1874  // const_cast such that voxel functions need only implement
1875  // non-const operator() which is required for parallel_reduce
1876  const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (im4, idx, p1, p2, p3, p4);
1877  } else const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(im4, idx, p1, p2, p3, p4);
1878  }
1879  }
1880 
1881  /// Process 2D image region
1882  void operator ()(const blocked_range2d<int> &re) const
1883  {
1884  const int bi = re.cols().begin();
1885  const int bj = re.rows().begin();
1886  const int ei = re.cols().end();
1887  const int ej = re.rows().end();
1888 
1889  const int s1 = im4.GetX() - (ei - bi);
1890 
1891  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1892  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1893  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1894  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1895 
1896  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
1897  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
1898  if (Domain::IsInside(im4, i, j, this->_k, this->_l, p4)) {
1899  // const_cast such that voxel functions need only implement
1900  // non-const operator() which is required for parallel_reduce
1901  const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4);
1902  } else const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
1903  }
1904  }
1905 
1906  /// Process 3D image region
1907  void operator ()(const blocked_range3d<int> &re) const
1908  {
1909  const int bi = re.cols ().begin();
1910  const int bj = re.rows ().begin();
1911  const int bk = re.pages().begin();
1912  const int ei = re.cols ().end();
1913  const int ej = re.rows ().end();
1914  const int ek = re.pages().end();
1915 
1916  const int s1 = im4.GetX() - (ei - bi);
1917  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
1918 
1919  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1920  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1921  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
1922  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
1923 
1924  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
1925  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
1926  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
1927  if (Domain::IsInside(im4, i, j, k, this->_l, p4)) {
1928  // const_cast such that voxel functions need only implement
1929  // non-const operator() which is required for parallel_reduce
1930  const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4);
1931  } else const_cast<QuaternaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4);
1932  }
1933  }
1934 };
1935 
1936 // -----------------------------------------------------------------------------
1937 // ForEachVoxel
1938 // -----------------------------------------------------------------------------
1939 
1940 //
1941 // Image arguments by pointer
1942 //
1943 
1944 // -----------------------------------------------------------------------------
1945 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1946 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
1947 {
1948  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
1949  blocked_range<int> re(0, im4->GetNumberOfVoxels());
1950  body(re);
1951  vf.join(body._VoxelFunc);
1952 }
1953 
1954 // -----------------------------------------------------------------------------
1955 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1956 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
1957 {
1958  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1959  ForEachScalar(*im1, *im2, *im3, *im4, vf);
1960 }
1961 
1962 // -----------------------------------------------------------------------------
1963 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1964 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
1965 {
1966  if (im4->GetTSize()) {
1967  ForEachScalar(*im1, *im2, *im3, *im4, vf);
1968  } else {
1969  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
1970  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
1971  body(re);
1972  vf.join(body._VoxelFunc);
1973  }
1974 }
1975 
1976 // -----------------------------------------------------------------------------
1977 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1978 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
1979 {
1980  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1981  ForEachVoxel(*im1, *im2, *im3, *im4, vf);
1982 }
1983 
1984 // -----------------------------------------------------------------------------
1985 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1986 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
1987 {
1988  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
1989  body(attr);
1990  vf.join(body._VoxelFunc);
1991 }
1992 
1993 // -----------------------------------------------------------------------------
1994 template <class T1, class T2, class T3, class T4, class VoxelFunc>
1995 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
1996 {
1997  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
1998  ForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
1999 }
2000 
2001 // -----------------------------------------------------------------------------
2002 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2003 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2004 {
2005  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2006  body(re);
2007  vf.join(body._VoxelFunc);
2008 }
2009 
2010 // -----------------------------------------------------------------------------
2011 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2012 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2013 {
2014  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2015  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
2016 }
2017 
2018 // -----------------------------------------------------------------------------
2019 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2020 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2021 {
2022  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2023  body(re);
2024  vf.join(body._VoxelFunc);
2025 }
2026 
2027 // -----------------------------------------------------------------------------
2028 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2029 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2030 {
2031  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2032  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
2033 }
2034 
2035 // -----------------------------------------------------------------------------
2036 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2037 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2038 {
2039  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2040  body(re);
2041  vf.join(body._VoxelFunc);
2042 }
2043 
2044 // -----------------------------------------------------------------------------
2045 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2046 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2047 {
2048  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2049  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
2050 }
2051 
2052 //
2053 // Image arguments by reference
2054 //
2055 
2056 // -----------------------------------------------------------------------------
2057 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2058 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2059 {
2062  body(re);
2063  vf.join(body._VoxelFunc);
2064 }
2065 
2066 // -----------------------------------------------------------------------------
2067 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2068 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2069 {
2070  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2071  ForEachScalar(im1, im2, im3, im4, vf);
2072 }
2073 
2074 // -----------------------------------------------------------------------------
2075 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2076 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2077 {
2078  if (im4.GetTSize()) {
2079  ForEachScalar(im1, im2, im3, im4, vf);
2080  } else {
2082  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
2083  body(re);
2084  vf.join(body._VoxelFunc);
2085  }
2086 }
2087 
2088 // -----------------------------------------------------------------------------
2089 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2090 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2091 {
2092  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2093  ForEachVoxel(im1, im2, im3, im4, vf);
2094 }
2095 
2096 // -----------------------------------------------------------------------------
2097 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2098 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2099 {
2101  body(attr);
2102  vf.join(body._VoxelFunc);
2103 }
2104 
2105 // -----------------------------------------------------------------------------
2106 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2107 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2108 {
2109  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2110  ForEachVoxel(attr, im1, im2, im3, im4, vf);
2111 }
2112 
2113 // -----------------------------------------------------------------------------
2114 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2115 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2116 {
2118  body(re);
2119  vf.join(body._VoxelFunc);
2120 }
2121 
2122 // -----------------------------------------------------------------------------
2123 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2124 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2125 {
2126  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2127  ForEachVoxel(re, im1, im2, im3, im4, vf);
2128 }
2129 
2130 // -----------------------------------------------------------------------------
2131 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2132 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2133 {
2135  body(re);
2136  vf.join(body._VoxelFunc);
2137 }
2138 
2139 // -----------------------------------------------------------------------------
2140 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2141 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2142 {
2143  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2144  ForEachVoxel(re, im1, im2, im3, im4, vf);
2145 }
2146 
2147 // -----------------------------------------------------------------------------
2148 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2149 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2150 {
2152  body(re);
2153  vf.join(body._VoxelFunc);
2154 }
2155 
2156 // -----------------------------------------------------------------------------
2157 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2158 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2159 {
2160  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2161  ForEachVoxel(re, im1, im2, im3, im4, vf);
2162 }
2163 
2164 // -----------------------------------------------------------------------------
2165 // ForEachVoxelIf
2166 // -----------------------------------------------------------------------------
2167 
2168 //
2169 // Image arguments by pointer
2170 //
2171 
2172 // -----------------------------------------------------------------------------
2173 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2174 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2175 {
2177  blocked_range<int> re(0, im4->GetNumberOfVoxels());
2178  body(re);
2179  vf.join(body._VoxelFunc);
2180  of.join(body._OutsideFunc);
2181 }
2182 
2183 // -----------------------------------------------------------------------------
2184 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2185 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2186 {
2187  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2188  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2189 }
2190 
2191 // -----------------------------------------------------------------------------
2192 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2193 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2194 {
2196  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2197 }
2198 
2199 // -----------------------------------------------------------------------------
2200 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2201 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2202 {
2203  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2204  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
2205 }
2206 
2207 // -----------------------------------------------------------------------------
2208 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2209 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2210 {
2211  if (im4->GetTSize()) {
2212  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2213  } else {
2215  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
2216  body(re);
2217  vf.join(body._VoxelFunc);
2218  of.join(body._OutsideFunc);
2219  }
2220 }
2221 
2222 // -----------------------------------------------------------------------------
2223 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2224 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2225 {
2226  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2227  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2228 }
2229 
2230 // -----------------------------------------------------------------------------
2231 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2232 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2233 {
2235  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2236 }
2237 
2238 // -----------------------------------------------------------------------------
2239 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2240 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2241 {
2242  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2243  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
2244 }
2245 
2246 // -----------------------------------------------------------------------------
2247 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2248 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2249 {
2251  body(attr);
2252  vf.join(body._VoxelFunc);
2253  of.join(body._OutsideFunc);
2254 }
2255 
2256 // -----------------------------------------------------------------------------
2257 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2258 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2259 {
2260  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2261  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
2262 }
2263 
2264 // -----------------------------------------------------------------------------
2265 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2266 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2267 {
2269  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
2270 }
2271 
2272 // -----------------------------------------------------------------------------
2273 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2274 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2275 {
2276  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2277  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
2278 }
2279 
2280 // -----------------------------------------------------------------------------
2281 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2282 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2283 {
2285  body(re);
2286  vf.join(body._VoxelFunc);
2287  of.join(body._OutsideFunc);
2288 }
2289 
2290 // -----------------------------------------------------------------------------
2291 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2292 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2293 {
2294  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2295  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
2296 }
2297 
2298 // -----------------------------------------------------------------------------
2299 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2300 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2301 {
2303  body(re);
2304  vf.join(body._VoxelFunc);
2305  of.join(body._OutsideFunc);
2306 }
2307 
2308 // -----------------------------------------------------------------------------
2309 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2310 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2311 {
2312  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2313  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
2314 }
2315 
2316 // -----------------------------------------------------------------------------
2317 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2318 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2319 {
2321  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
2322 }
2323 
2324 // -----------------------------------------------------------------------------
2325 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2326 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2327 {
2328  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2329  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
2330 }
2331 
2332 // -----------------------------------------------------------------------------
2333 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2334 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2335 {
2337  body(re);
2338  vf.join(body._VoxelFunc);
2339  of.join(body._OutsideFunc);
2340 }
2341 
2342 // -----------------------------------------------------------------------------
2343 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2344 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2345 {
2346  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2347  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2348 }
2349 
2350 // -----------------------------------------------------------------------------
2351 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2352 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2353 {
2355  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
2356 }
2357 
2358 // -----------------------------------------------------------------------------
2359 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2360 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2361 {
2362  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2363  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
2364 }
2365 
2366 //
2367 // Image arguments by reference
2368 //
2369 
2370 // -----------------------------------------------------------------------------
2371 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2372 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
2373 {
2376  body(re);
2377  vf.join(body._VoxelFunc);
2378  of.join(body._OutsideFunc);
2379 }
2380 
2381 // -----------------------------------------------------------------------------
2382 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2383 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2384 {
2385  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2386  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
2387 }
2388 
2389 // -----------------------------------------------------------------------------
2390 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2391 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2392 {
2394  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
2395 }
2396 
2397 // -----------------------------------------------------------------------------
2398 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2399 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2400 {
2401  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2402  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
2403 }
2404 
2405 // -----------------------------------------------------------------------------
2406 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2407 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
2408 {
2409  if (im4.GetTSize()) {
2410  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
2411  } else {
2413  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
2414  body(re);
2415  vf.join(body._VoxelFunc);
2416  of.join(body._OutsideFunc);
2417  }
2418 }
2419 
2420 // -----------------------------------------------------------------------------
2421 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2422 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2423 {
2424  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2425  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
2426 }
2427 
2428 // -----------------------------------------------------------------------------
2429 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2430 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2431 {
2433  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
2434 }
2435 
2436 // -----------------------------------------------------------------------------
2437 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2438 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2439 {
2440  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2441  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
2442 }
2443 
2444 // -----------------------------------------------------------------------------
2445 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2446 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
2447 {
2449  body(attr);
2450  vf.join(body._VoxelFunc);
2451  of.join(body._OutsideFunc);
2452 }
2453 
2454 // -----------------------------------------------------------------------------
2455 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2456 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2457 {
2458  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2459  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
2460 }
2461 
2462 // -----------------------------------------------------------------------------
2463 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2464 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2465 {
2467  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
2468 }
2469 
2470 // -----------------------------------------------------------------------------
2471 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2472 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2473 {
2474  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2475  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
2476 }
2477 
2478 // -----------------------------------------------------------------------------
2479 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2480 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
2481 {
2483  body(re);
2484  vf.join(body._VoxelFunc);
2485  of.join(body._OutsideFunc);
2486 }
2487 
2488 // -----------------------------------------------------------------------------
2489 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2490 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2491 {
2492  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2493  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
2494 }
2495 
2496 // -----------------------------------------------------------------------------
2497 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2498 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
2499 {
2501  body(re);
2502  vf.join(body._VoxelFunc);
2503  of.join(body._OutsideFunc);
2504 }
2505 
2506 // -----------------------------------------------------------------------------
2507 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2508 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2509 {
2510  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2511  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
2512 }
2513 
2514 // -----------------------------------------------------------------------------
2515 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2516 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2517 {
2519  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
2520 }
2521 
2522 // -----------------------------------------------------------------------------
2523 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2524 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2525 {
2526  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2527  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
2528 }
2529 
2530 // -----------------------------------------------------------------------------
2531 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2532 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
2533 {
2535  body(re);
2536  vf.join(body._VoxelFunc);
2537  of.join(body._OutsideFunc);
2538 }
2539 
2540 // -----------------------------------------------------------------------------
2541 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2542 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2543 {
2544  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2545  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
2546 }
2547 
2548 // -----------------------------------------------------------------------------
2549 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2550 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2551 {
2553  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
2554 }
2555 
2556 // -----------------------------------------------------------------------------
2557 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2558 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2559 {
2560  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2561  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
2562 }
2563 
2564 // -----------------------------------------------------------------------------
2565 // ParallelForEachVoxel
2566 // -----------------------------------------------------------------------------
2567 
2568 //
2569 // Image arguments by pointer
2570 //
2571 
2572 // -----------------------------------------------------------------------------
2573 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2574 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2575 {
2576  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2577  blocked_range<int> re(0, im4->GetNumberOfVoxels());
2578  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2579  else parallel_for (re, body);
2580 }
2581 
2582 // -----------------------------------------------------------------------------
2583 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2584 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2585 {
2586  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2587  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
2588 }
2589 
2590 // -----------------------------------------------------------------------------
2591 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2592 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2593 {
2594  if (im4->GetTSize()) {
2595  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
2596  } else {
2597  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2598  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
2599  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2600  else parallel_for (re, body);
2601  }
2602 }
2603 
2604 // -----------------------------------------------------------------------------
2605 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2606 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2607 {
2608  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2609  ParallelForEachVoxel(*im1, *im2, *im3, *im4, vf);
2610 }
2611 
2612 // -----------------------------------------------------------------------------
2613 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2614 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2615 {
2616  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2617  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2618  if (VoxelFunc::IsReduction()) {
2619  if (attr._dt) {
2620  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2621  } else {
2622  parallel_reduce(re, body);
2623  }
2624  vf.join(body._VoxelFunc);
2625  } else {
2626  if (attr._dt) {
2627  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2628  } else {
2629  parallel_for(re, body);
2630  }
2631  }
2632 }
2633 
2634 // -----------------------------------------------------------------------------
2635 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2636 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2637 {
2638  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2639  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
2640 }
2641 
2642 // -----------------------------------------------------------------------------
2643 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2644 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2645 {
2646  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2647  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2648  else parallel_for (re, body);
2649 }
2650 
2651 // -----------------------------------------------------------------------------
2652 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2653 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2654 {
2655  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2656  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
2657 }
2658 
2659 // -----------------------------------------------------------------------------
2660 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2661 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2662 {
2663  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2664  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2665  else parallel_for (re, body);
2666 }
2667 
2668 // -----------------------------------------------------------------------------
2669 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2670 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2671 {
2672  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2673  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
2674 }
2675 
2676 // -----------------------------------------------------------------------------
2677 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2678 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2679 {
2680  QuaternaryForEachVoxelBody_3Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
2681  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2682  else parallel_for (re, body);
2683 }
2684 
2685 // -----------------------------------------------------------------------------
2686 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2687 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2688 {
2689  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2690  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
2691 }
2692 
2693 //
2694 // Image arguments by reference
2695 //
2696 
2697 // -----------------------------------------------------------------------------
2698 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2699 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2700 {
2703  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2704  else parallel_for (re, body);
2705 }
2706 
2707 // -----------------------------------------------------------------------------
2708 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2709 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2710 {
2711  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2712  ParallelForEachScalar(im1, im2, im3, im4, vf);
2713 }
2714 
2715 // -----------------------------------------------------------------------------
2716 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2717 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2718 {
2719  if (im4.GetTSize()) {
2720  ParallelForEachScalar(im1, im2, im3, im4, vf);
2721  } else {
2723  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
2724  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2725  else parallel_for (re, body);
2726  }
2727 }
2728 
2729 // -----------------------------------------------------------------------------
2730 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2731 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2732 {
2733  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2734  ParallelForEachVoxel(im1, im2, im3, im4, vf);
2735 }
2736 
2737 // -----------------------------------------------------------------------------
2738 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2739 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2740 {
2742  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2743  if (VoxelFunc::IsReduction()) {
2744  if (attr._dt) {
2745  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2746  } else {
2747  parallel_reduce(re, body);
2748  }
2749  vf.join(body._VoxelFunc);
2750  } else {
2751  if (attr._dt) {
2752  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2753  } else {
2754  parallel_for(re, body);
2755  }
2756  }
2757 }
2758 
2759 // -----------------------------------------------------------------------------
2760 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2761 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2762 {
2763  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2764  ParallelForEachVoxel(attr, im1, im2, im3, im4, vf);
2765 }
2766 
2767 // -----------------------------------------------------------------------------
2768 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2769 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2770 {
2772  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2773  else parallel_for (re, body);
2774 }
2775 
2776 // -----------------------------------------------------------------------------
2777 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2778 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2779 {
2780  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2781  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
2782 }
2783 
2784 // -----------------------------------------------------------------------------
2785 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2786 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2787 {
2789  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2790  else parallel_for (re, body);
2791 }
2792 
2793 // -----------------------------------------------------------------------------
2794 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2795 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2796 {
2797  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2798  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
2799 }
2800 
2801 // -----------------------------------------------------------------------------
2802 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2803 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
2804 {
2806  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2807  else parallel_for (re, body);
2808 }
2809 
2810 // -----------------------------------------------------------------------------
2811 template <class T1, class T2, class T3, class T4, class VoxelFunc>
2812 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
2813 {
2814  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2815  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
2816 }
2817 
2818 // -----------------------------------------------------------------------------
2819 // ParallelForEachVoxelIf
2820 // -----------------------------------------------------------------------------
2821 
2822 //
2823 // Image arguments by pointer
2824 //
2825 
2826 // -----------------------------------------------------------------------------
2827 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2828 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2829 {
2831  blocked_range<int> re(0, im4->GetNumberOfVoxels());
2832  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2833  parallel_reduce(re, body);
2834  vf.join(body._VoxelFunc);
2835  of.join(body._OutsideFunc);
2836  } else {
2837  parallel_for(re, body);
2838  }
2839 }
2840 
2841 // -----------------------------------------------------------------------------
2842 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2843 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2844 {
2845  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2846  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2847 }
2848 
2849 // -----------------------------------------------------------------------------
2850 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2851 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2852 {
2854  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2855 }
2856 
2857 // -----------------------------------------------------------------------------
2858 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2859 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2860 {
2861  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2862  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
2863 }
2864 
2865 // -----------------------------------------------------------------------------
2866 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2867 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2868 {
2869  if (im4->GetTSize()) {
2870  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2871  } else {
2873  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
2874  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2875  parallel_reduce(re, body);
2876  vf.join(body._VoxelFunc);
2877  of.join(body._OutsideFunc);
2878  } else {
2879  parallel_for(re, body);
2880  }
2881  }
2882 }
2883 
2884 // -----------------------------------------------------------------------------
2885 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2886 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2887 {
2888  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2889  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2890 }
2891 
2892 // -----------------------------------------------------------------------------
2893 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2894 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2895 {
2897  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
2898 }
2899 
2900 // -----------------------------------------------------------------------------
2901 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2902 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2903 {
2904  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2905  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
2906 }
2907 
2908 // -----------------------------------------------------------------------------
2909 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2910 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2911 {
2913  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2914  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2915  if (attr._dt) {
2916  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2917  } else {
2918  parallel_reduce(re, body);
2919  }
2920  vf.join(body._VoxelFunc);
2921  of.join(body._OutsideFunc);
2922  } else {
2923  if (attr._dt) {
2924  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2925  } else {
2926  parallel_for(re, body);
2927  }
2928  }
2929 }
2930 
2931 // -----------------------------------------------------------------------------
2932 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2933 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2934 {
2935  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2936  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
2937 }
2938 
2939 // -----------------------------------------------------------------------------
2940 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2941 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2942 {
2944  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
2945 }
2946 
2947 // -----------------------------------------------------------------------------
2948 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2949 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2950 {
2951  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2952  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
2953 }
2954 
2955 // -----------------------------------------------------------------------------
2956 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2957 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2958 {
2960  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2961  parallel_reduce(re, body);
2962  vf.join(body._VoxelFunc);
2963  of.join(body._OutsideFunc);
2964  } else {
2965  parallel_for(re, body);
2966  }
2967 }
2968 
2969 // -----------------------------------------------------------------------------
2970 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2971 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2972 {
2973  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2974  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
2975 }
2976 
2977 // -----------------------------------------------------------------------------
2978 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2979 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
2980 {
2982  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
2983 }
2984 
2985 // -----------------------------------------------------------------------------
2986 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
2987 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
2988 {
2989  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
2990  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
2991 }
2992 
2993 // -----------------------------------------------------------------------------
2994 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
2995 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
2996 {
2998  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2999  parallel_reduce(re, body);
3000  vf.join(body._VoxelFunc);
3001  of.join(body._OutsideFunc);
3002  } else {
3003  parallel_for(re, body);
3004  }
3005 }
3006 
3007 // -----------------------------------------------------------------------------
3008 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3009 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
3010 {
3011  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3012  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3013 }
3014 
3015 // -----------------------------------------------------------------------------
3016 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3017 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3018 {
3020  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3021 }
3022 
3023 // -----------------------------------------------------------------------------
3024 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3025 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
3026 {
3027  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3028  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
3029 }
3030 
3031 // -----------------------------------------------------------------------------
3032 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3033 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3034 {
3036  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3037  parallel_reduce(re, body);
3038  vf.join(body._VoxelFunc);
3039  of.join(body._OutsideFunc);
3040  } else {
3041  parallel_for(re, body);
3042  }
3043 }
3044 
3045 // -----------------------------------------------------------------------------
3046 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3047 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
3048 {
3049  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3050  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3051 }
3052 
3053 // -----------------------------------------------------------------------------
3054 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3055 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3056 {
3058  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3059 }
3060 
3061 // -----------------------------------------------------------------------------
3062 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3063 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4)
3064 {
3065  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3066  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
3067 }
3068 
3069 //
3070 // Image arguments by reference
3071 //
3072 
3073 // -----------------------------------------------------------------------------
3074 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3075 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
3076 {
3079  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3080  parallel_reduce(re, body);
3081  vf.join(body._VoxelFunc);
3082  of.join(body._OutsideFunc);
3083  } else {
3084  parallel_for(re, body);
3085  }
3086 }
3087 
3088 // -----------------------------------------------------------------------------
3089 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3090 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3091 {
3092  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3093  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
3094 }
3095 
3096 // -----------------------------------------------------------------------------
3097 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3098 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3099 {
3101  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
3102 }
3103 
3104 // -----------------------------------------------------------------------------
3105 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3106 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3107 {
3108  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3109  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
3110 }
3111 
3112 // -----------------------------------------------------------------------------
3113 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3114 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
3115 {
3116  if (im4.GetTSize()) {
3117  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
3118  } else {
3120  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
3121  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3122  parallel_reduce(re, body);
3123  vf.join(body._VoxelFunc);
3124  of.join(body._OutsideFunc);
3125  } else {
3126  parallel_for(re, body);
3127  }
3128  }
3129 }
3130 
3131 // -----------------------------------------------------------------------------
3132 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3133 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3134 {
3135  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3136  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
3137 }
3138 
3139 // -----------------------------------------------------------------------------
3140 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3141 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3142 {
3144  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
3145 }
3146 
3147 // -----------------------------------------------------------------------------
3148 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3149 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3150 {
3151  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3152  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
3153 }
3154 
3155 // -----------------------------------------------------------------------------
3156 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3157 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
3158 {
3160  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
3161  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3162  if (attr._dt) {
3163  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
3164  } else {
3165  parallel_reduce(re, body);
3166  }
3167  vf.join(body._VoxelFunc);
3168  of.join(body._OutsideFunc);
3169  } else {
3170  if (attr._dt) {
3171  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
3172  } else {
3173  parallel_for(re, body);
3174  }
3175  }
3176 }
3177 
3178 // -----------------------------------------------------------------------------
3179 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3180 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3181 {
3182  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3183  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
3184 }
3185 
3186 // -----------------------------------------------------------------------------
3187 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3188 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3189 {
3191  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
3192 }
3193 
3194 // -----------------------------------------------------------------------------
3195 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3196 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3197 {
3198  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3199  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
3200 }
3201 
3202 // -----------------------------------------------------------------------------
3203 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3204 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
3205 {
3207  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3208  parallel_reduce(re, body);
3209  vf.join(body._VoxelFunc);
3210  of.join(body._OutsideFunc);
3211  } else {
3212  parallel_for(re, body);
3213  }
3214 }
3215 
3216 // -----------------------------------------------------------------------------
3217 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3218 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3219 {
3220  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3221  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
3222 }
3223 
3224 // -----------------------------------------------------------------------------
3225 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3226 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3227 {
3229  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
3230 }
3231 
3232 // -----------------------------------------------------------------------------
3233 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3234 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3235 {
3236  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3237  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
3238 }
3239 
3240 // -----------------------------------------------------------------------------
3241 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3242 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
3243 {
3245  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3246  parallel_reduce(re, body);
3247  vf.join(body._VoxelFunc);
3248  of.join(body._OutsideFunc);
3249  } else {
3250  parallel_for(re, body);
3251  }
3252 }
3253 
3254 // -----------------------------------------------------------------------------
3255 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3256 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3257 {
3258  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3259  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
3260 }
3261 
3262 // -----------------------------------------------------------------------------
3263 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3264 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3265 {
3267  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
3268 }
3269 
3270 // -----------------------------------------------------------------------------
3271 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3272 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3273 {
3274  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3275  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
3276 }
3277 
3278 // -----------------------------------------------------------------------------
3279 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3280 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
3281 {
3283  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3284  parallel_reduce(re, body);
3285  vf.join(body._VoxelFunc);
3286  of.join(body._OutsideFunc);
3287  } else {
3288  parallel_for(re, body);
3289  }
3290 }
3291 
3292 // -----------------------------------------------------------------------------
3293 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3294 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3295 {
3296  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3297  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
3298 }
3299 
3300 // -----------------------------------------------------------------------------
3301 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3302 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3303 {
3305  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
3306 }
3307 
3308 // -----------------------------------------------------------------------------
3309 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3310 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4)
3311 {
3312  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3313  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
3314 }
3315 
3316 // =============================================================================
3317 // 2 const, 2 non-const images
3318 // =============================================================================
3319 
3320 // -----------------------------------------------------------------------------
3321 /**
3322  * ForEachVoxel body for voxel function of 2 const, 2 non-const images
3323  */
3324 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3326 {
3327  const GenericImage<T1> &im1;
3328  const GenericImage<T2> &im2;
3329  GenericImage<T3> &im3;
3330  GenericImage<T4> &im4;
3331 
3332  /// Constructor
3334  const GenericImage<T2> &im2,
3335  GenericImage<T3> &im3,
3336  GenericImage<T4> &im4,
3337  VoxelFunc &vf)
3338  :
3339  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
3340  {}
3341 
3342  /// Copy constructor
3344  :
3345  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
3346  {}
3347 
3348  /// Split constructor
3350  :
3351  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
3352  {}
3353 
3354  /// Process entire image
3355  void operator ()(const ImageAttributes &attr) const
3356  {
3357  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3358  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3359  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
3360  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
3361 
3362  const int T = (attr._dt ? attr._t : 1);
3363 
3364  for (int l = 0; l < T; ++l)
3365  for (int k = 0; k < attr._z; ++k)
3366  for (int j = 0; j < attr._y; ++j)
3367  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
3368  // const_cast such that voxel functions need only implement
3369  // non-const operator() which is required for parallel_reduce
3370  const_cast<QuaternaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4);
3371  }
3372  }
3373 
3374  /// Process image region using linear index
3375  void operator ()(const blocked_range<int> &re) const
3376  {
3377  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3378  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3379  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
3380  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
3381 
3382  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
3383  // const_cast such that voxel functions need only implement
3384  // non-const operator() which is required for parallel_reduce
3385  const_cast<QuaternaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(im4, idx, p1, p2, p3, p4);
3386  }
3387  }
3388 
3389  /// Process 2D image region
3390  void operator ()(const blocked_range2d<int> &re) const
3391  {
3392  const int bi = re.cols().begin();
3393  const int bj = re.rows().begin();
3394  const int ei = re.cols().end();
3395  const int ej = re.rows().end();
3396 
3397  const int s1 = im4.GetX() - (ei - bi);
3398 
3399  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3400  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3401  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3402  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3403 
3404  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
3405  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
3406  // const_cast such that voxel functions need only implement
3407  // non-const operator() which is required for parallel_reduce
3408  const_cast<QuaternaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
3409  }
3410  }
3411 
3412  /// Process 3D image region
3413  void operator ()(const blocked_range3d<int> &re) const
3414  {
3415  const int bi = re.cols ().begin();
3416  const int bj = re.rows ().begin();
3417  const int bk = re.pages().begin();
3418  const int ei = re.cols ().end();
3419  const int ej = re.rows ().end();
3420  const int ek = re.pages().end();
3421 
3422  const int s1 = im4.GetX() - (ei - bi);
3423  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
3424 
3425  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3426  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3427  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
3428  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
3429 
3430  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
3431  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
3432  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
3433  // const_cast such that voxel functions need only implement
3434  // non-const operator() which is required for parallel_reduce
3435  const_cast<QuaternaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4);
3436  }
3437  }
3438 };
3439 
3440 // -----------------------------------------------------------------------------
3441 /**
3442  * ForEachVoxel body for inside and outside unary voxel function of 2 const, 2 non-const images
3443  */
3444 template <class T1, class T2, class T3, class T4,
3445  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
3446  class Domain = ForEachVoxelDomain::Foreground>
3447 struct QuaternaryForEachVoxelIfBody_2Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
3448 {
3449  const GenericImage<T1> &im1;
3450  const GenericImage<T2> &im2;
3451  GenericImage<T3> &im3;
3452  GenericImage<T4> &im4;
3453 
3454  /// Constructor
3456  const GenericImage<T2> &im2,
3457  GenericImage<T3> &im3,
3458  GenericImage<T4> &im4,
3459  VoxelFunc &vf, OutsideFunc &of)
3460  :
3461  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
3462  {}
3463 
3464  /// Copy constructor
3466  :
3467  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
3468  {}
3469 
3470  /// Split constructor
3472  :
3473  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
3474  {}
3475 
3476  /// Process entire image
3477  void operator ()(const ImageAttributes &attr) const
3478  {
3479  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3480  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3481  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
3482  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
3483 
3484  const int T = (attr._dt ? attr._t : 1);
3485 
3486  for (int l = 0; l < T; ++l)
3487  for (int k = 0; k < attr._z; ++k)
3488  for (int j = 0; j < attr._y; ++j)
3489  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
3490  if (Domain::IsInside(im4, i, j, k, l, p4)) {
3491  // const_cast such that voxel functions need only implement
3492  // non-const operator() which is required for parallel_reduce
3493  const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4);
3494  } else const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4);
3495  }
3496  }
3497 
3498  /// Process image region using linear index
3499  void operator ()(const blocked_range<int> &re) const
3500  {
3501  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3502  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3503  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
3504  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
3505 
3506  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
3507  if (Domain::IsInside(im4, idx, p4)) {
3508  // const_cast such that voxel functions need only implement
3509  // non-const operator() which is required for parallel_reduce
3510  const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (im4, idx, p1, p2, p3, p4);
3511  } else const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(im4, idx, p1, p2, p3, p4);
3512  }
3513  }
3514 
3515  /// Process 2D image region
3516  void operator ()(const blocked_range2d<int> &re) const
3517  {
3518  const int bi = re.cols().begin();
3519  const int bj = re.rows().begin();
3520  const int ei = re.cols().end();
3521  const int ej = re.rows().end();
3522 
3523  const int s1 = im4.GetX() - (ei - bi);
3524 
3525  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3526  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3527  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3528  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3529 
3530  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
3531  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
3532  if (Domain::IsInside(im4, i, j, this->_k, this->_l, p4)) {
3533  // const_cast such that voxel functions need only implement
3534  // non-const operator() which is required for parallel_reduce
3535  const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4);
3536  } else const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
3537  }
3538  }
3539 
3540  /// Process 3D image region
3541  void operator ()(const blocked_range3d<int> &re) const
3542  {
3543  const int bi = re.cols ().begin();
3544  const int bj = re.rows ().begin();
3545  const int bk = re.pages().begin();
3546  const int ei = re.cols ().end();
3547  const int ej = re.rows ().end();
3548  const int ek = re.pages().end();
3549 
3550  const int s1 = im4.GetX() - (ei - bi);
3551  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
3552 
3553  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3554  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3555  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
3556  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
3557 
3558  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
3559  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
3560  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
3561  if (Domain::IsInside(im4, i, j, k, this->_l, p4)) {
3562  // const_cast such that voxel functions need only implement
3563  // non-const operator() which is required for parallel_reduce
3564  const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4);
3565  } else const_cast<QuaternaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4);
3566  }
3567  }
3568 };
3569 
3570 // -----------------------------------------------------------------------------
3571 // ForEachVoxel
3572 // -----------------------------------------------------------------------------
3573 
3574 //
3575 // Image arguments by pointer
3576 //
3577 
3578 // -----------------------------------------------------------------------------
3579 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3580 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3581 {
3582  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
3583  blocked_range<int> re(0, im4->GetNumberOfVoxels());
3584  body(re);
3585  vf.join(body._VoxelFunc);
3586 }
3587 
3588 // -----------------------------------------------------------------------------
3589 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3590 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3591 {
3592  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3593  ForEachScalar(*im1, *im2, *im3, *im4, vf);
3594 }
3595 
3596 // -----------------------------------------------------------------------------
3597 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3598 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3599 {
3600  if (im4->GetTSize()) {
3601  ForEachScalar(*im1, *im2, *im3, *im4, vf);
3602  } else {
3603  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
3604  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
3605  body(re);
3606  vf.join(body._VoxelFunc);
3607  }
3608 }
3609 
3610 // -----------------------------------------------------------------------------
3611 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3612 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3613 {
3614  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3615  ForEachVoxel(*im1, *im2, *im3, *im4, vf);
3616 }
3617 
3618 // -----------------------------------------------------------------------------
3619 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3620 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3621 {
3622  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
3623  body(attr);
3624  vf.join(body._VoxelFunc);
3625 }
3626 
3627 // -----------------------------------------------------------------------------
3628 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3629 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3630 {
3631  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3632  ForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
3633 }
3634 
3635 // -----------------------------------------------------------------------------
3636 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3637 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3638 {
3639  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
3640  body(re);
3641  vf.join(body._VoxelFunc);
3642 }
3643 
3644 // -----------------------------------------------------------------------------
3645 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3646 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3647 {
3648  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3649  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
3650 }
3651 
3652 // -----------------------------------------------------------------------------
3653 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3654 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3655 {
3656  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
3657  body(re);
3658  vf.join(body._VoxelFunc);
3659 }
3660 
3661 // -----------------------------------------------------------------------------
3662 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3663 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3664 {
3665  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3666  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
3667 }
3668 
3669 // -----------------------------------------------------------------------------
3670 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3671 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3672 {
3673  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
3674  body(re);
3675  vf.join(body._VoxelFunc);
3676 }
3677 
3678 // -----------------------------------------------------------------------------
3679 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3680 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3681 {
3682  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3683  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
3684 }
3685 
3686 //
3687 // Image arguments by reference
3688 //
3689 
3690 // -----------------------------------------------------------------------------
3691 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3692 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3693 {
3696  body(re);
3697  vf.join(body._VoxelFunc);
3698 }
3699 
3700 // -----------------------------------------------------------------------------
3701 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3702 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
3703 {
3704  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3705  ForEachScalar(im1, im2, im3, im4, vf);
3706 }
3707 
3708 // -----------------------------------------------------------------------------
3709 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3710 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3711 {
3712  if (im4.GetTSize()) {
3713  ForEachScalar(im1, im2, im3, im4, vf);
3714  } else {
3716  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
3717  body(re);
3718  vf.join(body._VoxelFunc);
3719  }
3720 }
3721 
3722 // -----------------------------------------------------------------------------
3723 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3724 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
3725 {
3726  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3727  ForEachVoxel(im1, im2, im3, im4, vf);
3728 }
3729 
3730 // -----------------------------------------------------------------------------
3731 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3732 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3733 {
3735  body(attr);
3736  vf.join(body._VoxelFunc);
3737 }
3738 
3739 // -----------------------------------------------------------------------------
3740 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3741 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
3742 {
3743  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3744  ForEachVoxel(attr, im1, im2, im3, im4, vf);
3745 }
3746 
3747 // -----------------------------------------------------------------------------
3748 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3749 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3750 {
3752  body(re);
3753  vf.join(body._VoxelFunc);
3754 }
3755 
3756 // -----------------------------------------------------------------------------
3757 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3758 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
3759 {
3760  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3761  ForEachVoxel(re, im1, im2, im3, im4, vf);
3762 }
3763 
3764 // -----------------------------------------------------------------------------
3765 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3766 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3767 {
3769  body(re);
3770  vf.join(body._VoxelFunc);
3771 }
3772 
3773 // -----------------------------------------------------------------------------
3774 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3775 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
3776 {
3777  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3778  ForEachVoxel(re, im1, im2, im3, im4, vf);
3779 }
3780 
3781 // -----------------------------------------------------------------------------
3782 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3783 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
3784 {
3786  body(re);
3787  vf.join(body._VoxelFunc);
3788 }
3789 
3790 // -----------------------------------------------------------------------------
3791 template <class T1, class T2, class T3, class T4, class VoxelFunc>
3792 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
3793 {
3794  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3795  ForEachVoxel(re, im1, im2, im3, im4, vf);
3796 }
3797 
3798 // -----------------------------------------------------------------------------
3799 // ForEachVoxelIf
3800 // -----------------------------------------------------------------------------
3801 
3802 //
3803 // Image arguments by pointer
3804 //
3805 
3806 // -----------------------------------------------------------------------------
3807 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3808 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3809 {
3811  blocked_range<int> re(0, im4->GetNumberOfVoxels());
3812  body(re);
3813  vf.join(body._VoxelFunc);
3814  of.join(body._OutsideFunc);
3815 }
3816 
3817 // -----------------------------------------------------------------------------
3818 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3819 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3820 {
3821  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3822  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
3823 }
3824 
3825 // -----------------------------------------------------------------------------
3826 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3827 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3828 {
3830  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
3831 }
3832 
3833 // -----------------------------------------------------------------------------
3834 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3835 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3836 {
3837  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3838  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
3839 }
3840 
3841 // -----------------------------------------------------------------------------
3842 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3843 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3844 {
3845  if (im4->GetTSize()) {
3846  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
3847  } else {
3849  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
3850  body(re);
3851  vf.join(body._VoxelFunc);
3852  of.join(body._OutsideFunc);
3853  }
3854 }
3855 
3856 // -----------------------------------------------------------------------------
3857 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3858 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3859 {
3860  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3861  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
3862 }
3863 
3864 // -----------------------------------------------------------------------------
3865 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3866 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3867 {
3869  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
3870 }
3871 
3872 // -----------------------------------------------------------------------------
3873 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3874 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3875 {
3876  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3877  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
3878 }
3879 
3880 // -----------------------------------------------------------------------------
3881 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3882 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3883 {
3885  body(attr);
3886  vf.join(body._VoxelFunc);
3887  of.join(body._OutsideFunc);
3888 }
3889 
3890 // -----------------------------------------------------------------------------
3891 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3892 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3893 {
3894  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3895  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
3896 }
3897 
3898 // -----------------------------------------------------------------------------
3899 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3900 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3901 {
3903  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
3904 }
3905 
3906 // -----------------------------------------------------------------------------
3907 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3908 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3909 {
3910  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3911  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
3912 }
3913 
3914 // -----------------------------------------------------------------------------
3915 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3916 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3917 {
3919  body(re);
3920  vf.join(body._VoxelFunc);
3921  of.join(body._OutsideFunc);
3922 }
3923 
3924 // -----------------------------------------------------------------------------
3925 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3926 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3927 {
3928  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3929  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3930 }
3931 
3932 // -----------------------------------------------------------------------------
3933 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3934 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3935 {
3937  body(re);
3938  vf.join(body._VoxelFunc);
3939  of.join(body._OutsideFunc);
3940 }
3941 
3942 // -----------------------------------------------------------------------------
3943 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3944 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3945 {
3946  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3947  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3948 }
3949 
3950 // -----------------------------------------------------------------------------
3951 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3952 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3953 {
3955  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3956 }
3957 
3958 // -----------------------------------------------------------------------------
3959 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3960 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3961 {
3962  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3963  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
3964 }
3965 
3966 // -----------------------------------------------------------------------------
3967 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3968 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
3969 {
3971  body(re);
3972  vf.join(body._VoxelFunc);
3973  of.join(body._OutsideFunc);
3974 }
3975 
3976 // -----------------------------------------------------------------------------
3977 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
3978 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3979 {
3980  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3981  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
3982 }
3983 
3984 // -----------------------------------------------------------------------------
3985 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3986 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
3987 {
3989  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
3990 }
3991 
3992 // -----------------------------------------------------------------------------
3993 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
3994 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
3995 {
3996  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
3997  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
3998 }
3999 
4000 //
4001 // Image arguments by reference
4002 //
4003 
4004 // -----------------------------------------------------------------------------
4005 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4006 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4007 {
4010  body(re);
4011  vf.join(body._VoxelFunc);
4012  of.join(body._OutsideFunc);
4013 }
4014 
4015 // -----------------------------------------------------------------------------
4016 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4017 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4018 {
4019  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4020  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
4021 }
4022 
4023 // -----------------------------------------------------------------------------
4024 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4025 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4026 {
4028  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
4029 }
4030 
4031 // -----------------------------------------------------------------------------
4032 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4033 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4034 {
4035  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4036  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
4037 }
4038 
4039 // -----------------------------------------------------------------------------
4040 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4041 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4042 {
4043  if (im4.GetTSize()) {
4044  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
4045  } else {
4047  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
4048  body(re);
4049  vf.join(body._VoxelFunc);
4050  of.join(body._OutsideFunc);
4051  }
4052 }
4053 
4054 // -----------------------------------------------------------------------------
4055 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4056 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4057 {
4058  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4059  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
4060 }
4061 
4062 // -----------------------------------------------------------------------------
4063 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4064 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4065 {
4067  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
4068 }
4069 
4070 // -----------------------------------------------------------------------------
4071 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4072 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4073 {
4074  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4075  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
4076 }
4077 
4078 // -----------------------------------------------------------------------------
4079 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4080 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4081 {
4083  body(attr);
4084  vf.join(body._VoxelFunc);
4085  of.join(body._OutsideFunc);
4086 }
4087 
4088 // -----------------------------------------------------------------------------
4089 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4090 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4091 {
4092  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4093  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
4094 }
4095 
4096 // -----------------------------------------------------------------------------
4097 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4098 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4099 {
4101  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
4102 }
4103 
4104 // -----------------------------------------------------------------------------
4105 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4106 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4107 {
4108  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4109  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
4110 }
4111 
4112 // -----------------------------------------------------------------------------
4113 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4114 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4115 {
4117  body(re);
4118  vf.join(body._VoxelFunc);
4119  of.join(body._OutsideFunc);
4120 }
4121 
4122 // -----------------------------------------------------------------------------
4123 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4124 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4125 {
4126  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4127  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4128 }
4129 
4130 // -----------------------------------------------------------------------------
4131 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4132 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4133 {
4135  body(re);
4136  vf.join(body._VoxelFunc);
4137  of.join(body._OutsideFunc);
4138 }
4139 
4140 // -----------------------------------------------------------------------------
4141 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4142 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4143 {
4144  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4145  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4146 }
4147 
4148 // -----------------------------------------------------------------------------
4149 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4150 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4151 {
4153  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4154 }
4155 
4156 // -----------------------------------------------------------------------------
4157 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4158 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4159 {
4160  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4161  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
4162 }
4163 
4164 // -----------------------------------------------------------------------------
4165 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4166 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4167 {
4169  body(re);
4170  vf.join(body._VoxelFunc);
4171  of.join(body._OutsideFunc);
4172 }
4173 
4174 // -----------------------------------------------------------------------------
4175 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4176 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4177 {
4178  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4179  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4180 }
4181 
4182 // -----------------------------------------------------------------------------
4183 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4184 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4185 {
4187  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4188 }
4189 
4190 // -----------------------------------------------------------------------------
4191 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4192 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4193 {
4194  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4195  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
4196 }
4197 
4198 // -----------------------------------------------------------------------------
4199 // ParallelForEachVoxel
4200 // -----------------------------------------------------------------------------
4201 
4202 //
4203 // Image arguments by pointer
4204 //
4205 
4206 // -----------------------------------------------------------------------------
4207 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4208 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4209 {
4210  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
4211  blocked_range<int> re(0, im4->GetNumberOfVoxels());
4212  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4213  else parallel_for (re, body);
4214 }
4215 
4216 // -----------------------------------------------------------------------------
4217 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4218 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4219 {
4220  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4221  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
4222 }
4223 
4224 // -----------------------------------------------------------------------------
4225 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4226 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4227 {
4228  if (im4->GetTSize()) {
4229  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
4230  } else {
4231  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
4232  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
4233  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4234  else parallel_for (re, body);
4235  }
4236 }
4237 
4238 // -----------------------------------------------------------------------------
4239 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4240 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4241 {
4242  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4243  ParallelForEachVoxel(*im1, *im2, *im3, *im4, vf);
4244 }
4245 
4246 // -----------------------------------------------------------------------------
4247 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4248 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4249 {
4250  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
4251  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4252  if (VoxelFunc::IsReduction()) {
4253  if (attr._dt) {
4254  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4255  } else {
4256  parallel_reduce(re, body);
4257  }
4258  vf.join(body._VoxelFunc);
4259  } else {
4260  if (attr._dt) {
4261  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4262  } else {
4263  parallel_for(re, body);
4264  }
4265  }
4266 }
4267 
4268 // -----------------------------------------------------------------------------
4269 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4270 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4271 {
4272  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4273  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
4274 }
4275 
4276 // -----------------------------------------------------------------------------
4277 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4278 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4279 {
4280  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
4281  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4282  else parallel_for (re, body);
4283 }
4284 
4285 // -----------------------------------------------------------------------------
4286 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4287 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4288 {
4289  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4290  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
4291 }
4292 
4293 // -----------------------------------------------------------------------------
4294 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4295 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4296 {
4297  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
4298  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4299  else parallel_for (re, body);
4300 }
4301 
4302 // -----------------------------------------------------------------------------
4303 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4304 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4305 {
4306  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4307  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
4308 }
4309 
4310 // -----------------------------------------------------------------------------
4311 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4312 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4313 {
4314  QuaternaryForEachVoxelBody_2Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
4315  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4316  else parallel_for (re, body);
4317 }
4318 
4319 // -----------------------------------------------------------------------------
4320 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4321 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4322 {
4323  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4324  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
4325 }
4326 
4327 //
4328 // Image arguments by reference
4329 //
4330 
4331 // -----------------------------------------------------------------------------
4332 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4333 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4334 {
4337  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4338  else parallel_for (re, body);
4339 }
4340 
4341 // -----------------------------------------------------------------------------
4342 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4343 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4344 {
4345  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4346  ParallelForEachScalar(im1, im2, im3, im4, vf);
4347 }
4348 
4349 // -----------------------------------------------------------------------------
4350 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4351 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4352 {
4353  if (im4.GetTSize()) {
4354  ParallelForEachScalar(im1, im2, im3, im4, vf);
4355  } else {
4357  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
4358  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4359  else parallel_for (re, body);
4360  }
4361 }
4362 
4363 // -----------------------------------------------------------------------------
4364 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4365 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4366 {
4367  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4368  ParallelForEachVoxel(im1, im2, im3, im4, vf);
4369 }
4370 
4371 // -----------------------------------------------------------------------------
4372 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4373 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4374 {
4376  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4377  if (VoxelFunc::IsReduction()) {
4378  if (attr._dt) {
4379  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4380  } else {
4381  parallel_reduce(re, body);
4382  }
4383  vf.join(body._VoxelFunc);
4384  } else {
4385  if (attr._dt) {
4386  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4387  } else {
4388  parallel_for(re, body);
4389  }
4390  }
4391 }
4392 
4393 // -----------------------------------------------------------------------------
4394 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4395 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4396 {
4397  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4398  ParallelForEachVoxel(attr, im1, im2, im3, im4, vf);
4399 }
4400 
4401 // -----------------------------------------------------------------------------
4402 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4403 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4404 {
4406  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4407  else parallel_for (re, body);
4408 }
4409 
4410 // -----------------------------------------------------------------------------
4411 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4412 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4413 {
4414  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4415  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
4416 }
4417 
4418 // -----------------------------------------------------------------------------
4419 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4420 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4421 {
4423  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4424  else parallel_for (re, body);
4425 }
4426 
4427 // -----------------------------------------------------------------------------
4428 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4429 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4430 {
4431  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4432  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
4433 }
4434 
4435 // -----------------------------------------------------------------------------
4436 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4437 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4438 {
4440  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4441  else parallel_for (re, body);
4442 }
4443 
4444 // -----------------------------------------------------------------------------
4445 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4446 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4447 {
4448  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4449  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
4450 }
4451 
4452 // -----------------------------------------------------------------------------
4453 // ParallelForEachVoxelIf
4454 // -----------------------------------------------------------------------------
4455 
4456 //
4457 // Image arguments by pointer
4458 //
4459 
4460 // -----------------------------------------------------------------------------
4461 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4462 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
4463 {
4465  blocked_range<int> re(0, im4->GetNumberOfVoxels());
4466  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4467  parallel_reduce(re, body);
4468  vf.join(body._VoxelFunc);
4469  of.join(body._OutsideFunc);
4470  } else {
4471  parallel_for(re, body);
4472  }
4473 }
4474 
4475 // -----------------------------------------------------------------------------
4476 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4477 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4478 {
4479  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4480  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
4481 }
4482 
4483 // -----------------------------------------------------------------------------
4484 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4485 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4486 {
4488  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
4489 }
4490 
4491 // -----------------------------------------------------------------------------
4492 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4493 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4494 {
4495  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4496  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
4497 }
4498 
4499 // -----------------------------------------------------------------------------
4500 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4501 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
4502 {
4503  if (im4->GetTSize()) {
4504  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
4505  } else {
4507  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
4508  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4509  parallel_reduce(re, body);
4510  vf.join(body._VoxelFunc);
4511  of.join(body._OutsideFunc);
4512  } else {
4513  parallel_for(re, body);
4514  }
4515  }
4516 }
4517 
4518 // -----------------------------------------------------------------------------
4519 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4520 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4521 {
4522  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4523  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
4524 }
4525 
4526 // -----------------------------------------------------------------------------
4527 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4528 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4529 {
4531  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
4532 }
4533 
4534 // -----------------------------------------------------------------------------
4535 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4536 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4537 {
4538  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4539  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
4540 }
4541 
4542 // -----------------------------------------------------------------------------
4543 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4544 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
4545 {
4547  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4548  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4549  if (attr._dt) {
4550  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4551  } else {
4552  parallel_reduce(re, body);
4553  }
4554  vf.join(body._VoxelFunc);
4555  of.join(body._OutsideFunc);
4556  } else {
4557  if (attr._dt) {
4558  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4559  } else {
4560  parallel_for(re, body);
4561  }
4562  }
4563 }
4564 
4565 // -----------------------------------------------------------------------------
4566 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4567 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4568 {
4569  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4570  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
4571 }
4572 
4573 // -----------------------------------------------------------------------------
4574 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4575 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4576 {
4578  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
4579 }
4580 
4581 // -----------------------------------------------------------------------------
4582 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4583 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4584 {
4585  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4586  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
4587 }
4588 
4589 // -----------------------------------------------------------------------------
4590 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4591 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
4592 {
4594  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4595  parallel_reduce(re, body);
4596  vf.join(body._VoxelFunc);
4597  of.join(body._OutsideFunc);
4598  } else {
4599  parallel_for(re, body);
4600  }
4601 }
4602 
4603 // -----------------------------------------------------------------------------
4604 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4605 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4606 {
4607  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4608  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
4609 }
4610 
4611 // -----------------------------------------------------------------------------
4612 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4613 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4614 {
4616  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
4617 }
4618 
4619 // -----------------------------------------------------------------------------
4620 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4621 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4622 {
4623  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4624  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
4625 }
4626 
4627 // -----------------------------------------------------------------------------
4628 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4629 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
4630 {
4632  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4633  parallel_reduce(re, body);
4634  vf.join(body._VoxelFunc);
4635  of.join(body._OutsideFunc);
4636  } else {
4637  parallel_for(re, body);
4638  }
4639 }
4640 
4641 // -----------------------------------------------------------------------------
4642 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4643 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4644 {
4645  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4646  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
4647 }
4648 
4649 // -----------------------------------------------------------------------------
4650 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4651 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4652 {
4654  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
4655 }
4656 
4657 // -----------------------------------------------------------------------------
4658 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4659 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4660 {
4661  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4662  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
4663 }
4664 
4665 // -----------------------------------------------------------------------------
4666 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4667 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
4668 {
4670  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4671  parallel_reduce(re, body);
4672  vf.join(body._VoxelFunc);
4673  of.join(body._OutsideFunc);
4674  } else {
4675  parallel_for(re, body);
4676  }
4677 }
4678 
4679 // -----------------------------------------------------------------------------
4680 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4681 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4682 {
4683  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4684  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
4685 }
4686 
4687 // -----------------------------------------------------------------------------
4688 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4689 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
4690 {
4692  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
4693 }
4694 
4695 // -----------------------------------------------------------------------------
4696 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4697 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
4698 {
4699  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4700  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
4701 }
4702 
4703 //
4704 // Image arguments by reference
4705 //
4706 
4707 // -----------------------------------------------------------------------------
4708 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4709 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4710 {
4713  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4714  parallel_reduce(re, body);
4715  vf.join(body._VoxelFunc);
4716  of.join(body._OutsideFunc);
4717  } else {
4718  parallel_for(re, body);
4719  }
4720 }
4721 
4722 // -----------------------------------------------------------------------------
4723 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4724 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4725 {
4726  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4727  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
4728 }
4729 
4730 // -----------------------------------------------------------------------------
4731 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4732 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4733 {
4735  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
4736 }
4737 
4738 // -----------------------------------------------------------------------------
4739 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4740 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4741 {
4742  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4743  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
4744 }
4745 
4746 // -----------------------------------------------------------------------------
4747 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4748 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4749 {
4750  if (im4.GetTSize()) {
4751  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
4752  } else {
4754  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
4755  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4756  parallel_reduce(re, body);
4757  vf.join(body._VoxelFunc);
4758  of.join(body._OutsideFunc);
4759  } else {
4760  parallel_for(re, body);
4761  }
4762  }
4763 }
4764 
4765 // -----------------------------------------------------------------------------
4766 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4767 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4768 {
4769  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4770  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
4771 }
4772 
4773 // -----------------------------------------------------------------------------
4774 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4775 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4776 {
4778  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
4779 }
4780 
4781 // -----------------------------------------------------------------------------
4782 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4783 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4784 {
4785  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4786  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
4787 }
4788 
4789 // -----------------------------------------------------------------------------
4790 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4791 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4792 {
4794  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4795  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4796  if (attr._dt) {
4797  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4798  } else {
4799  parallel_reduce(re, body);
4800  }
4801  vf.join(body._VoxelFunc);
4802  of.join(body._OutsideFunc);
4803  } else {
4804  if (attr._dt) {
4805  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4806  } else {
4807  parallel_for(re, body);
4808  }
4809  }
4810 }
4811 
4812 // -----------------------------------------------------------------------------
4813 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4814 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4815 {
4816  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4817  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
4818 }
4819 
4820 // -----------------------------------------------------------------------------
4821 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4822 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4823 {
4825  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
4826 }
4827 
4828 // -----------------------------------------------------------------------------
4829 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4830 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4831 {
4832  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4833  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
4834 }
4835 
4836 // -----------------------------------------------------------------------------
4837 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4838 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4839 {
4841  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4842  parallel_reduce(re, body);
4843  vf.join(body._VoxelFunc);
4844  of.join(body._OutsideFunc);
4845  } else {
4846  parallel_for(re, body);
4847  }
4848 }
4849 
4850 // -----------------------------------------------------------------------------
4851 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4852 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4853 {
4854  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4855  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4856 }
4857 
4858 // -----------------------------------------------------------------------------
4859 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4860 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4861 {
4863  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4864 }
4865 
4866 // -----------------------------------------------------------------------------
4867 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4868 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4869 {
4870  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4871  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
4872 }
4873 
4874 // -----------------------------------------------------------------------------
4875 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4876 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4877 {
4879  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4880  parallel_reduce(re, body);
4881  vf.join(body._VoxelFunc);
4882  of.join(body._OutsideFunc);
4883  } else {
4884  parallel_for(re, body);
4885  }
4886 }
4887 
4888 // -----------------------------------------------------------------------------
4889 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4890 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4891 {
4892  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4893  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4894 }
4895 
4896 // -----------------------------------------------------------------------------
4897 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4898 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4899 {
4901  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4902 }
4903 
4904 // -----------------------------------------------------------------------------
4905 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4906 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4907 {
4908  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4909  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
4910 }
4911 
4912 // -----------------------------------------------------------------------------
4913 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4914 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
4915 {
4917  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4918  parallel_reduce(re, body);
4919  vf.join(body._VoxelFunc);
4920  of.join(body._OutsideFunc);
4921  } else {
4922  parallel_for(re, body);
4923  }
4924 }
4925 
4926 // -----------------------------------------------------------------------------
4927 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
4928 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4929 {
4930  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4931  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4932 }
4933 
4934 // -----------------------------------------------------------------------------
4935 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4936 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
4937 {
4939  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
4940 }
4941 
4942 // -----------------------------------------------------------------------------
4943 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
4944 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
4945 {
4946  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
4947  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
4948 }
4949 
4950 // =============================================================================
4951 // 1 const, 3 non-const images
4952 // =============================================================================
4953 
4954 // -----------------------------------------------------------------------------
4955 /**
4956  * ForEachVoxel body for voxel function of 1 const, 3 non-const images
4957  */
4958 template <class T1, class T2, class T3, class T4, class VoxelFunc>
4960 {
4961  const GenericImage<T1> &im1;
4962  GenericImage<T2> &im2;
4963  GenericImage<T3> &im3;
4964  GenericImage<T4> &im4;
4965 
4966  /// Constructor
4968  GenericImage<T2> &im2,
4969  GenericImage<T3> &im3,
4970  GenericImage<T4> &im4,
4971  VoxelFunc &vf)
4972  :
4973  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
4974  {}
4975 
4976  /// Copy constructor
4978  :
4979  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
4980  {}
4981 
4982  /// Split constructor
4984  :
4985  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
4986  {}
4987 
4988  /// Process entire image
4989  void operator ()(const ImageAttributes &attr) const
4990  {
4991  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
4992  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
4993  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
4994  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
4995 
4996  const int T = (attr._dt ? attr._t : 1);
4997 
4998  for (int l = 0; l < T; ++l)
4999  for (int k = 0; k < attr._z; ++k)
5000  for (int j = 0; j < attr._y; ++j)
5001  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
5002  // const_cast such that voxel functions need only implement
5003  // non-const operator() which is required for parallel_reduce
5004  const_cast<QuaternaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4);
5005  }
5006  }
5007 
5008  /// Process image region using linear index
5009  void operator ()(const blocked_range<int> &re) const
5010  {
5011  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
5012  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
5013  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
5014  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
5015 
5016  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
5017  // const_cast such that voxel functions need only implement
5018  // non-const operator() which is required for parallel_reduce
5019  const_cast<QuaternaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(im4, idx, p1, p2, p3, p4);
5020  }
5021  }
5022 
5023  /// Process 2D image region
5024  void operator ()(const blocked_range2d<int> &re) const
5025  {
5026  const int bi = re.cols().begin();
5027  const int bj = re.rows().begin();
5028  const int ei = re.cols().end();
5029  const int ej = re.rows().end();
5030 
5031  const int s1 = im4.GetX() - (ei - bi);
5032 
5033  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5034  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5035  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5036  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5037 
5038  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
5039  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
5040  // const_cast such that voxel functions need only implement
5041  // non-const operator() which is required for parallel_reduce
5042  const_cast<QuaternaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
5043  }
5044  }
5045 
5046  /// Process 3D image region
5047  void operator ()(const blocked_range3d<int> &re) const
5048  {
5049  const int bi = re.cols ().begin();
5050  const int bj = re.rows ().begin();
5051  const int bk = re.pages().begin();
5052  const int ei = re.cols ().end();
5053  const int ej = re.rows ().end();
5054  const int ek = re.pages().end();
5055 
5056  const int s1 = im4.GetX() - (ei - bi);
5057  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
5058 
5059  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
5060  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
5061  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
5062  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
5063 
5064  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
5065  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
5066  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
5067  // const_cast such that voxel functions need only implement
5068  // non-const operator() which is required for parallel_reduce
5069  const_cast<QuaternaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4);
5070  }
5071  }
5072 };
5073 
5074 // -----------------------------------------------------------------------------
5075 /**
5076  * ForEachVoxel body for inside and outside unary voxel function of 1 const, 3 non-const images
5077  */
5078 template <class T1, class T2, class T3, class T4,
5079  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
5080  class Domain = ForEachVoxelDomain::Foreground>
5081 struct QuaternaryForEachVoxelIfBody_1Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
5082 {
5083  const GenericImage<T1> &im1;
5084  GenericImage<T2> &im2;
5085  GenericImage<T3> &im3;
5086  GenericImage<T4> &im4;
5087 
5088  /// Constructor
5090  GenericImage<T2> &im2,
5091  GenericImage<T3> &im3,
5092  GenericImage<T4> &im4,
5093  VoxelFunc &vf, OutsideFunc &of)
5094  :
5095  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
5096  {}
5097 
5098  /// Copy constructor
5100  :
5101  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
5102  {}
5103 
5104  /// Split constructor
5106  :
5107  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
5108  {}
5109 
5110  /// Process entire image
5111  void operator ()(const ImageAttributes &attr) const
5112  {
5113  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
5114  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
5115  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
5116  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
5117 
5118  const int T = (attr._dt ? attr._t : 1);
5119 
5120  for (int l = 0; l < T; ++l)
5121  for (int k = 0; k < attr._z; ++k)
5122  for (int j = 0; j < attr._y; ++j)
5123  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
5124  if (Domain::IsInside(im4, i, j, k, l, p4)) {
5125  // const_cast such that voxel functions need only implement
5126  // non-const operator() which is required for parallel_reduce
5127  const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4);
5128  } else const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4);
5129  }
5130  }
5131 
5132  /// Process image region using linear index
5133  void operator ()(const blocked_range<int> &re) const
5134  {
5135  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
5136  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
5137  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
5138  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
5139 
5140  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
5141  if (Domain::IsInside(im4, idx, p4)) {
5142  // const_cast such that voxel functions need only implement
5143  // non-const operator() which is required for parallel_reduce
5144  const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (im4, idx, p1, p2, p3, p4);
5145  } else const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(im4, idx, p1, p2, p3, p4);
5146  }
5147  }
5148 
5149  /// Process 2D image region
5150  void operator ()(const blocked_range2d<int> &re) const
5151  {
5152  const int bi = re.cols().begin();
5153  const int bj = re.rows().begin();
5154  const int ei = re.cols().end();
5155  const int ej = re.rows().end();
5156 
5157  const int s1 = im4.GetX() - (ei - bi);
5158 
5159  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5160  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5161  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5162  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5163 
5164  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
5165  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
5166  if (Domain::IsInside(im4, i, j, this->_k, this->_l, p4)) {
5167  // const_cast such that voxel functions need only implement
5168  // non-const operator() which is required for parallel_reduce
5169  const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4);
5170  } else const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
5171  }
5172  }
5173 
5174  /// Process 3D image region
5175  void operator ()(const blocked_range3d<int> &re) const
5176  {
5177  const int bi = re.cols ().begin();
5178  const int bj = re.rows ().begin();
5179  const int bk = re.pages().begin();
5180  const int ei = re.cols ().end();
5181  const int ej = re.rows ().end();
5182  const int ek = re.pages().end();
5183 
5184  const int s1 = im4.GetX() - (ei - bi);
5185  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
5186 
5187  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
5188  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
5189  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
5190  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
5191 
5192  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
5193  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
5194  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
5195  if (Domain::IsInside(im4, i, j, k, this->_l, p4)) {
5196  // const_cast such that voxel functions need only implement
5197  // non-const operator() which is required for parallel_reduce
5198  const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4);
5199  } else const_cast<QuaternaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4);
5200  }
5201  }
5202 };
5203 
5204 // -----------------------------------------------------------------------------
5205 // ForEachVoxel
5206 // -----------------------------------------------------------------------------
5207 
5208 //
5209 // Image arguments by pointer
5210 //
5211 
5212 // -----------------------------------------------------------------------------
5213 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5214 void ForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5215 {
5216  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5217  blocked_range<int> re(0, im4->GetNumberOfVoxels());
5218  body(re);
5219  vf.join(body._VoxelFunc);
5220 }
5221 
5222 // -----------------------------------------------------------------------------
5223 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5224 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5225 {
5226  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5227  ForEachScalar(*im1, *im2, *im3, *im4, vf);
5228 }
5229 
5230 // -----------------------------------------------------------------------------
5231 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5232 void ForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5233 {
5234  if (im4->GetTSize()) {
5235  ForEachScalar(*im1, *im2, *im3, *im4, vf);
5236  } else {
5237  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5238  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
5239  body(re);
5240  vf.join(body._VoxelFunc);
5241  }
5242 }
5243 
5244 // -----------------------------------------------------------------------------
5245 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5246 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5247 {
5248  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5249  ForEachVoxel(*im1, *im2, *im3, *im4, vf);
5250 }
5251 
5252 // -----------------------------------------------------------------------------
5253 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5254 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5255 {
5256  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5257  body(attr);
5258  vf.join(body._VoxelFunc);
5259 }
5260 
5261 // -----------------------------------------------------------------------------
5262 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5263 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5264 {
5265  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5266  ForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
5267 }
5268 
5269 // -----------------------------------------------------------------------------
5270 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5271 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5272 {
5273  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5274  body(re);
5275  vf.join(body._VoxelFunc);
5276 }
5277 
5278 // -----------------------------------------------------------------------------
5279 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5280 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5281 {
5282  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5283  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
5284 }
5285 
5286 // -----------------------------------------------------------------------------
5287 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5288 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5289 {
5290  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5291  body(re);
5292  vf.join(body._VoxelFunc);
5293 }
5294 
5295 // -----------------------------------------------------------------------------
5296 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5297 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5298 {
5299  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5300  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
5301 }
5302 
5303 // -----------------------------------------------------------------------------
5304 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5305 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5306 {
5307  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5308  body(re);
5309  vf.join(body._VoxelFunc);
5310 }
5311 
5312 // -----------------------------------------------------------------------------
5313 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5314 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5315 {
5316  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5317  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
5318 }
5319 
5320 //
5321 // Image arguments by reference
5322 //
5323 
5324 // -----------------------------------------------------------------------------
5325 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5326 void ForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5327 {
5330  body(re);
5331  vf.join(body._VoxelFunc);
5332 }
5333 
5334 // -----------------------------------------------------------------------------
5335 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5336 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5337 {
5338  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5339  ForEachScalar(im1, im2, im3, im4, vf);
5340 }
5341 
5342 // -----------------------------------------------------------------------------
5343 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5344 void ForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5345 {
5346  if (im4.GetTSize()) {
5347  ForEachScalar(im1, im2, im3, im4, vf);
5348  } else {
5350  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
5351  body(re);
5352  vf.join(body._VoxelFunc);
5353  }
5354 }
5355 
5356 // -----------------------------------------------------------------------------
5357 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5358 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5359 {
5360  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5361  ForEachVoxel(im1, im2, im3, im4, vf);
5362 }
5363 
5364 // -----------------------------------------------------------------------------
5365 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5366 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5367 {
5369  body(attr);
5370  vf.join(body._VoxelFunc);
5371 }
5372 
5373 // -----------------------------------------------------------------------------
5374 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5375 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5376 {
5377  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5378  ForEachVoxel(attr, im1, im2, im3, im4, vf);
5379 }
5380 
5381 // -----------------------------------------------------------------------------
5382 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5383 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5384 {
5386  body(re);
5387  vf.join(body._VoxelFunc);
5388 }
5389 
5390 // -----------------------------------------------------------------------------
5391 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5392 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5393 {
5394  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5395  ForEachVoxel(re, im1, im2, im3, im4, vf);
5396 }
5397 
5398 // -----------------------------------------------------------------------------
5399 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5400 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5401 {
5403  body(re);
5404  vf.join(body._VoxelFunc);
5405 }
5406 
5407 // -----------------------------------------------------------------------------
5408 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5409 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5410 {
5411  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5412  ForEachVoxel(re, im1, im2, im3, im4, vf);
5413 }
5414 
5415 // -----------------------------------------------------------------------------
5416 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5417 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5418 {
5420  body(re);
5421  vf.join(body._VoxelFunc);
5422 }
5423 
5424 // -----------------------------------------------------------------------------
5425 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5426 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5427 {
5428  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5429  ForEachVoxel(re, im1, im2, im3, im4, vf);
5430 }
5431 
5432 // -----------------------------------------------------------------------------
5433 // ForEachVoxelIf
5434 // -----------------------------------------------------------------------------
5435 
5436 //
5437 // Image arguments by pointer
5438 //
5439 
5440 // -----------------------------------------------------------------------------
5441 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5442 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
5443 {
5445  blocked_range<int> re(0, im4->GetNumberOfVoxels());
5446  body(re);
5447  vf.join(body._VoxelFunc);
5448  of.join(body._OutsideFunc);
5449 }
5450 
5451 // -----------------------------------------------------------------------------
5452 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5453 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5454 {
5455  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5456  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
5457 }
5458 
5459 // -----------------------------------------------------------------------------
5460 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5461 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5462 {
5464  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
5465 }
5466 
5467 // -----------------------------------------------------------------------------
5468 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5469 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5470 {
5471  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5472  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
5473 }
5474 
5475 // -----------------------------------------------------------------------------
5476 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5477 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
5478 {
5479  if (im4->GetTSize()) {
5480  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
5481  } else {
5483  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
5484  body(re);
5485  vf.join(body._VoxelFunc);
5486  of.join(body._OutsideFunc);
5487  }
5488 }
5489 
5490 // -----------------------------------------------------------------------------
5491 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5492 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5493 {
5494  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5495  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
5496 }
5497 
5498 // -----------------------------------------------------------------------------
5499 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5500 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5501 {
5503  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
5504 }
5505 
5506 // -----------------------------------------------------------------------------
5507 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5508 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5509 {
5510  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5511  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
5512 }
5513 
5514 // -----------------------------------------------------------------------------
5515 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5516 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
5517 {
5519  body(attr);
5520  vf.join(body._VoxelFunc);
5521  of.join(body._OutsideFunc);
5522 }
5523 
5524 // -----------------------------------------------------------------------------
5525 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5526 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5527 {
5528  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5529  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
5530 }
5531 
5532 // -----------------------------------------------------------------------------
5533 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5534 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5535 {
5537  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
5538 }
5539 
5540 // -----------------------------------------------------------------------------
5541 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5542 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5543 {
5544  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5545  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
5546 }
5547 
5548 // -----------------------------------------------------------------------------
5549 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5550 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
5551 {
5553  body(re);
5554  vf.join(body._VoxelFunc);
5555  of.join(body._OutsideFunc);
5556 }
5557 
5558 // -----------------------------------------------------------------------------
5559 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5560 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5561 {
5562  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5563  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
5564 }
5565 
5566 // -----------------------------------------------------------------------------
5567 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5568 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
5569 {
5571  body(re);
5572  vf.join(body._VoxelFunc);
5573  of.join(body._OutsideFunc);
5574 }
5575 
5576 // -----------------------------------------------------------------------------
5577 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5578 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5579 {
5580  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5581  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
5582 }
5583 
5584 // -----------------------------------------------------------------------------
5585 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5586 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5587 {
5589  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
5590 }
5591 
5592 // -----------------------------------------------------------------------------
5593 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5594 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5595 {
5596  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5597  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
5598 }
5599 
5600 // -----------------------------------------------------------------------------
5601 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5602 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
5603 {
5605  body(re);
5606  vf.join(body._VoxelFunc);
5607  of.join(body._OutsideFunc);
5608 }
5609 
5610 // -----------------------------------------------------------------------------
5611 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5612 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5613 {
5614  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5615  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
5616 }
5617 
5618 // -----------------------------------------------------------------------------
5619 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5620 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5621 {
5623  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
5624 }
5625 
5626 // -----------------------------------------------------------------------------
5627 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5628 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5629 {
5630  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5631  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
5632 }
5633 
5634 //
5635 // Image arguments by reference
5636 //
5637 
5638 // -----------------------------------------------------------------------------
5639 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5640 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
5641 {
5644  body(re);
5645  vf.join(body._VoxelFunc);
5646  of.join(body._OutsideFunc);
5647 }
5648 
5649 // -----------------------------------------------------------------------------
5650 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5651 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5652 {
5653  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5654  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
5655 }
5656 
5657 // -----------------------------------------------------------------------------
5658 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5659 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5660 {
5662  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
5663 }
5664 
5665 // -----------------------------------------------------------------------------
5666 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5667 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5668 {
5669  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5670  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
5671 }
5672 
5673 // -----------------------------------------------------------------------------
5674 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5675 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
5676 {
5677  if (im4.GetTSize()) {
5678  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
5679  } else {
5681  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
5682  body(re);
5683  vf.join(body._VoxelFunc);
5684  of.join(body._OutsideFunc);
5685  }
5686 }
5687 
5688 // -----------------------------------------------------------------------------
5689 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5690 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5691 {
5692  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5693  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
5694 }
5695 
5696 // -----------------------------------------------------------------------------
5697 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5698 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5699 {
5701  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
5702 }
5703 
5704 // -----------------------------------------------------------------------------
5705 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5706 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5707 {
5708  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5709  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
5710 }
5711 
5712 // -----------------------------------------------------------------------------
5713 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5714 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
5715 {
5717  body(attr);
5718  vf.join(body._VoxelFunc);
5719  of.join(body._OutsideFunc);
5720 }
5721 
5722 // -----------------------------------------------------------------------------
5723 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5724 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5725 {
5726  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5727  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
5728 }
5729 
5730 // -----------------------------------------------------------------------------
5731 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5732 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5733 {
5735  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
5736 }
5737 
5738 // -----------------------------------------------------------------------------
5739 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5740 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5741 {
5742  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5743  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
5744 }
5745 
5746 // -----------------------------------------------------------------------------
5747 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5748 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
5749 {
5751  body(re);
5752  vf.join(body._VoxelFunc);
5753  of.join(body._OutsideFunc);
5754 }
5755 
5756 // -----------------------------------------------------------------------------
5757 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5758 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5759 {
5760  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5761  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
5762 }
5763 
5764 // -----------------------------------------------------------------------------
5765 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5766 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
5767 {
5769  body(re);
5770  vf.join(body._VoxelFunc);
5771  of.join(body._OutsideFunc);
5772 }
5773 
5774 // -----------------------------------------------------------------------------
5775 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5776 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5777 {
5778  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5779  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
5780 }
5781 
5782 // -----------------------------------------------------------------------------
5783 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5784 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5785 {
5787  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
5788 }
5789 
5790 // -----------------------------------------------------------------------------
5791 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5792 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5793 {
5794  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5795  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
5796 }
5797 
5798 // -----------------------------------------------------------------------------
5799 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5800 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
5801 {
5803  body(re);
5804  vf.join(body._VoxelFunc);
5805  of.join(body._OutsideFunc);
5806 }
5807 
5808 // -----------------------------------------------------------------------------
5809 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
5810 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5811 {
5812  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5813  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
5814 }
5815 
5816 // -----------------------------------------------------------------------------
5817 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5818 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5819 {
5821  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
5822 }
5823 
5824 // -----------------------------------------------------------------------------
5825 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
5826 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5827 {
5828  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5829  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
5830 }
5831 
5832 // -----------------------------------------------------------------------------
5833 // ParallelForEachVoxel
5834 // -----------------------------------------------------------------------------
5835 
5836 //
5837 // Image arguments by pointer
5838 //
5839 
5840 // -----------------------------------------------------------------------------
5841 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5842 void ParallelForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5843 {
5844  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5845  blocked_range<int> re(0, im4->GetNumberOfVoxels());
5846  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5847  else parallel_for (re, body);
5848 }
5849 
5850 // -----------------------------------------------------------------------------
5851 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5852 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5853 {
5854  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5855  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
5856 }
5857 
5858 // -----------------------------------------------------------------------------
5859 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5860 void ParallelForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5861 {
5862  if (im4->GetTSize()) {
5863  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
5864  } else {
5865  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5866  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
5867  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5868  else parallel_for (re, body);
5869  }
5870 }
5871 
5872 // -----------------------------------------------------------------------------
5873 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5874 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5875 {
5876  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5877  ParallelForEachVoxel(*im1, *im2, *im3, *im4, vf);
5878 }
5879 
5880 // -----------------------------------------------------------------------------
5881 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5882 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5883 {
5884  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5885  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
5886  if (VoxelFunc::IsReduction()) {
5887  if (attr._dt) {
5888  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
5889  } else {
5890  parallel_reduce(re, body);
5891  }
5892  vf.join(body._VoxelFunc);
5893  } else {
5894  if (attr._dt) {
5895  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
5896  } else {
5897  parallel_for(re, body);
5898  }
5899  }
5900 }
5901 
5902 // -----------------------------------------------------------------------------
5903 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5904 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5905 {
5906  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5907  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
5908 }
5909 
5910 // -----------------------------------------------------------------------------
5911 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5912 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5913 {
5914  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5915  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5916  else parallel_for (re, body);
5917 }
5918 
5919 // -----------------------------------------------------------------------------
5920 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5921 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5922 {
5923  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5924  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
5925 }
5926 
5927 // -----------------------------------------------------------------------------
5928 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5929 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5930 {
5931  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5932  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5933  else parallel_for (re, body);
5934 }
5935 
5936 // -----------------------------------------------------------------------------
5937 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5938 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5939 {
5940  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5941  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
5942 }
5943 
5944 // -----------------------------------------------------------------------------
5945 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5946 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
5947 {
5948  QuaternaryForEachVoxelBody_1Const<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
5949  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5950  else parallel_for (re, body);
5951 }
5952 
5953 // -----------------------------------------------------------------------------
5954 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5955 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
5956 {
5957  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5958  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
5959 }
5960 
5961 //
5962 // Image arguments by reference
5963 //
5964 
5965 // -----------------------------------------------------------------------------
5966 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5967 void ParallelForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5968 {
5971  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5972  else parallel_for (re, body);
5973 }
5974 
5975 // -----------------------------------------------------------------------------
5976 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5977 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
5978 {
5979  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
5980  ParallelForEachScalar(im1, im2, im3, im4, vf);
5981 }
5982 
5983 // -----------------------------------------------------------------------------
5984 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5985 void ParallelForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
5986 {
5987  if (im4.GetTSize()) {
5988  ParallelForEachScalar(im1, im2, im3, im4, vf);
5989  } else {
5991  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
5992  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5993  else parallel_for (re, body);
5994  }
5995 }
5996 
5997 // -----------------------------------------------------------------------------
5998 template <class T1, class T2, class T3, class T4, class VoxelFunc>
5999 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6000 {
6001  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6002  ParallelForEachVoxel(im1, im2, im3, im4, vf);
6003 }
6004 
6005 // -----------------------------------------------------------------------------
6006 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6007 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6008 {
6010  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6011  if (VoxelFunc::IsReduction()) {
6012  if (attr._dt) {
6013  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6014  } else {
6015  parallel_reduce(re, body);
6016  }
6017  vf.join(body._VoxelFunc);
6018  } else {
6019  if (attr._dt) {
6020  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6021  } else {
6022  parallel_for(re, body);
6023  }
6024  }
6025 }
6026 
6027 // -----------------------------------------------------------------------------
6028 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6029 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6030 {
6031  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6032  ParallelForEachVoxel(attr, im1, im2, im3, im4, vf);
6033 }
6034 
6035 // -----------------------------------------------------------------------------
6036 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6037 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6038 {
6040  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6041  else parallel_for (re, body);
6042 }
6043 
6044 // -----------------------------------------------------------------------------
6045 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6046 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6047 {
6048  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6049  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
6050 }
6051 
6052 // -----------------------------------------------------------------------------
6053 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6054 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6055 {
6057  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6058  else parallel_for (re, body);
6059 }
6060 
6061 // -----------------------------------------------------------------------------
6062 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6063 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6064 {
6065  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6066  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
6067 }
6068 
6069 // -----------------------------------------------------------------------------
6070 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6071 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6072 {
6074  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6075  else parallel_for (re, body);
6076 }
6077 
6078 // -----------------------------------------------------------------------------
6079 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6080 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6081 {
6082  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6083  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
6084 }
6085 
6086 // -----------------------------------------------------------------------------
6087 // ParallelForEachVoxelIf
6088 // -----------------------------------------------------------------------------
6089 
6090 //
6091 // Image arguments by pointer
6092 //
6093 
6094 // -----------------------------------------------------------------------------
6095 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6096 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
6097 {
6099  blocked_range<int> re(0, im4->GetNumberOfVoxels());
6100  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6101  parallel_reduce(re, body);
6102  vf.join(body._VoxelFunc);
6103  of.join(body._OutsideFunc);
6104  } else {
6105  parallel_for(re, body);
6106  }
6107 }
6108 
6109 // -----------------------------------------------------------------------------
6110 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6111 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6112 {
6113  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6114  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
6115 }
6116 
6117 // -----------------------------------------------------------------------------
6118 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6119 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6120 {
6122  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
6123 }
6124 
6125 // -----------------------------------------------------------------------------
6126 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6127 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6128 {
6129  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6130  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
6131 }
6132 
6133 // -----------------------------------------------------------------------------
6134 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6135 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
6136 {
6137  if (im4->GetTSize()) {
6138  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
6139  } else {
6141  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
6142  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6143  parallel_reduce(re, body);
6144  vf.join(body._VoxelFunc);
6145  of.join(body._OutsideFunc);
6146  } else {
6147  parallel_for(re, body);
6148  }
6149  }
6150 }
6151 
6152 // -----------------------------------------------------------------------------
6153 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6154 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6155 {
6156  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6157  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
6158 }
6159 
6160 // -----------------------------------------------------------------------------
6161 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6162 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6163 {
6165  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
6166 }
6167 
6168 // -----------------------------------------------------------------------------
6169 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6170 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6171 {
6172  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6173  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
6174 }
6175 
6176 // -----------------------------------------------------------------------------
6177 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6178 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
6179 {
6181  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6182  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6183  if (attr._dt) {
6184  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6185  } else {
6186  parallel_reduce(re, body);
6187  }
6188  vf.join(body._VoxelFunc);
6189  of.join(body._OutsideFunc);
6190  } else {
6191  if (attr._dt) {
6192  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6193  } else {
6194  parallel_for(re, body);
6195  }
6196  }
6197 }
6198 
6199 // -----------------------------------------------------------------------------
6200 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6201 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6202 {
6203  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6204  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
6205 }
6206 
6207 // -----------------------------------------------------------------------------
6208 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6209 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6210 {
6212  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
6213 }
6214 
6215 // -----------------------------------------------------------------------------
6216 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6217 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6218 {
6219  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6220  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
6221 }
6222 
6223 // -----------------------------------------------------------------------------
6224 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6225 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
6226 {
6228  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6229  parallel_reduce(re, body);
6230  vf.join(body._VoxelFunc);
6231  of.join(body._OutsideFunc);
6232  } else {
6233  parallel_for(re, body);
6234  }
6235 }
6236 
6237 // -----------------------------------------------------------------------------
6238 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6239 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6240 {
6241  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6242  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
6243 }
6244 
6245 // -----------------------------------------------------------------------------
6246 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6247 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6248 {
6250  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
6251 }
6252 
6253 // -----------------------------------------------------------------------------
6254 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6255 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6256 {
6257  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6258  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
6259 }
6260 
6261 // -----------------------------------------------------------------------------
6262 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6263 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
6264 {
6266  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6267  parallel_reduce(re, body);
6268  vf.join(body._VoxelFunc);
6269  of.join(body._OutsideFunc);
6270  } else {
6271  parallel_for(re, body);
6272  }
6273 }
6274 
6275 // -----------------------------------------------------------------------------
6276 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6277 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6278 {
6279  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6280  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
6281 }
6282 
6283 // -----------------------------------------------------------------------------
6284 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6285 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6286 {
6288  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
6289 }
6290 
6291 // -----------------------------------------------------------------------------
6292 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6293 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6294 {
6295  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6296  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
6297 }
6298 
6299 // -----------------------------------------------------------------------------
6300 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6301 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
6302 {
6304  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6305  parallel_reduce(re, body);
6306  vf.join(body._VoxelFunc);
6307  of.join(body._OutsideFunc);
6308  } else {
6309  parallel_for(re, body);
6310  }
6311 }
6312 
6313 // -----------------------------------------------------------------------------
6314 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6315 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6316 {
6317  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6318  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
6319 }
6320 
6321 // -----------------------------------------------------------------------------
6322 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6323 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6324 {
6326  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
6327 }
6328 
6329 // -----------------------------------------------------------------------------
6330 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6331 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6332 {
6333  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6334  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
6335 }
6336 
6337 //
6338 // Image arguments by reference
6339 //
6340 
6341 // -----------------------------------------------------------------------------
6342 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6343 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
6344 {
6347  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6348  parallel_reduce(re, body);
6349  vf.join(body._VoxelFunc);
6350  of.join(body._OutsideFunc);
6351  } else {
6352  parallel_for(re, body);
6353  }
6354 }
6355 
6356 // -----------------------------------------------------------------------------
6357 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6358 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6359 {
6360  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6361  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
6362 }
6363 
6364 // -----------------------------------------------------------------------------
6365 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6366 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6367 {
6369  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
6370 }
6371 
6372 // -----------------------------------------------------------------------------
6373 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6374 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6375 {
6376  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6377  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
6378 }
6379 
6380 // -----------------------------------------------------------------------------
6381 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6382 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
6383 {
6384  if (im4.GetTSize()) {
6385  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
6386  } else {
6388  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
6389  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6390  parallel_reduce(re, body);
6391  vf.join(body._VoxelFunc);
6392  of.join(body._OutsideFunc);
6393  } else {
6394  parallel_for(re, body);
6395  }
6396  }
6397 }
6398 
6399 // -----------------------------------------------------------------------------
6400 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6401 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6402 {
6403  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6404  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
6405 }
6406 
6407 // -----------------------------------------------------------------------------
6408 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6409 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6410 {
6412  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
6413 }
6414 
6415 // -----------------------------------------------------------------------------
6416 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6417 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6418 {
6419  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6420  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
6421 }
6422 
6423 // -----------------------------------------------------------------------------
6424 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6425 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
6426 {
6428  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6429  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6430  if (attr._dt) {
6431  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6432  } else {
6433  parallel_reduce(re, body);
6434  }
6435  vf.join(body._VoxelFunc);
6436  of.join(body._OutsideFunc);
6437  } else {
6438  if (attr._dt) {
6439  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6440  } else {
6441  parallel_for(re, body);
6442  }
6443  }
6444 }
6445 
6446 // -----------------------------------------------------------------------------
6447 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6448 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6449 {
6450  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6451  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
6452 }
6453 
6454 // -----------------------------------------------------------------------------
6455 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6456 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6457 {
6459  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
6460 }
6461 
6462 // -----------------------------------------------------------------------------
6463 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6464 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6465 {
6466  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6467  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
6468 }
6469 
6470 // -----------------------------------------------------------------------------
6471 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6472 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
6473 {
6475  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6476  parallel_reduce(re, body);
6477  vf.join(body._VoxelFunc);
6478  of.join(body._OutsideFunc);
6479  } else {
6480  parallel_for(re, body);
6481  }
6482 }
6483 
6484 // -----------------------------------------------------------------------------
6485 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6486 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6487 {
6488  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6489  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
6490 }
6491 
6492 // -----------------------------------------------------------------------------
6493 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6494 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6495 {
6497  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
6498 }
6499 
6500 // -----------------------------------------------------------------------------
6501 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6502 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6503 {
6504  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6505  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
6506 }
6507 
6508 // -----------------------------------------------------------------------------
6509 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6510 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
6511 {
6513  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6514  parallel_reduce(re, body);
6515  vf.join(body._VoxelFunc);
6516  of.join(body._OutsideFunc);
6517  } else {
6518  parallel_for(re, body);
6519  }
6520 }
6521 
6522 // -----------------------------------------------------------------------------
6523 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6524 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6525 {
6526  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6527  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
6528 }
6529 
6530 // -----------------------------------------------------------------------------
6531 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6532 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6533 {
6535  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
6536 }
6537 
6538 // -----------------------------------------------------------------------------
6539 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6540 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6541 {
6542  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6543  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
6544 }
6545 
6546 // -----------------------------------------------------------------------------
6547 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6548 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
6549 {
6551  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6552  parallel_reduce(re, body);
6553  vf.join(body._VoxelFunc);
6554  of.join(body._OutsideFunc);
6555  } else {
6556  parallel_for(re, body);
6557  }
6558 }
6559 
6560 // -----------------------------------------------------------------------------
6561 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
6562 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6563 {
6564  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6565  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
6566 }
6567 
6568 // -----------------------------------------------------------------------------
6569 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6570 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6571 {
6573  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
6574 }
6575 
6576 // -----------------------------------------------------------------------------
6577 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
6578 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6579 {
6580  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6581  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
6582 }
6583 
6584 // =============================================================================
6585 // 4 non-const images
6586 // =============================================================================
6587 
6588 // -----------------------------------------------------------------------------
6589 /**
6590  * ForEachVoxel body for voxel function of 4 non-const images
6591  */
6592 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6594 {
6595  GenericImage<T1> &im1;
6596  GenericImage<T2> &im2;
6597  GenericImage<T3> &im3;
6598  GenericImage<T4> &im4;
6599 
6600  /// Constructor
6602  GenericImage<T2> &im2,
6603  GenericImage<T3> &im3,
6604  GenericImage<T4> &im4,
6605  VoxelFunc &vf)
6606  :
6607  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
6608  {}
6609 
6610  /// Copy constructor
6612  :
6613  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
6614  {}
6615 
6616  /// Split constructor
6618  :
6619  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
6620  {}
6621 
6622  /// Process entire image
6623  void operator ()(const ImageAttributes &attr) const
6624  {
6625  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
6626  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
6627  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
6628  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
6629 
6630  const int T = (attr._dt ? attr._t : 1);
6631 
6632  for (int l = 0; l < T; ++l)
6633  for (int k = 0; k < attr._z; ++k)
6634  for (int j = 0; j < attr._y; ++j)
6635  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
6636  // const_cast such that voxel functions need only implement
6637  // non-const operator() which is required for parallel_reduce
6638  const_cast<QuaternaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4);
6639  }
6640  }
6641 
6642  /// Process image region using linear index
6643  void operator ()(const blocked_range<int> &re) const
6644  {
6645  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
6646  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
6647  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
6648  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
6649 
6650  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
6651  // const_cast such that voxel functions need only implement
6652  // non-const operator() which is required for parallel_reduce
6653  const_cast<QuaternaryForEachVoxelBody *>(this)->_VoxelFunc(im4, idx, p1, p2, p3, p4);
6654  }
6655  }
6656 
6657  /// Process 2D image region
6658  void operator ()(const blocked_range2d<int> &re) const
6659  {
6660  const int bi = re.cols().begin();
6661  const int bj = re.rows().begin();
6662  const int ei = re.cols().end();
6663  const int ej = re.rows().end();
6664 
6665  const int s1 = im4.GetX() - (ei - bi);
6666 
6667  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6668  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6669  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6670  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6671 
6672  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
6673  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
6674  // const_cast such that voxel functions need only implement
6675  // non-const operator() which is required for parallel_reduce
6676  const_cast<QuaternaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
6677  }
6678  }
6679 
6680  /// Process 3D image region
6681  void operator ()(const blocked_range3d<int> &re) const
6682  {
6683  const int bi = re.cols ().begin();
6684  const int bj = re.rows ().begin();
6685  const int bk = re.pages().begin();
6686  const int ei = re.cols ().end();
6687  const int ej = re.rows ().end();
6688  const int ek = re.pages().end();
6689 
6690  const int s1 = im4.GetX() - (ei - bi);
6691  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
6692 
6693  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
6694  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
6695  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
6696  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
6697 
6698  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
6699  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
6700  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
6701  // const_cast such that voxel functions need only implement
6702  // non-const operator() which is required for parallel_reduce
6703  const_cast<QuaternaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4);
6704  }
6705  }
6706 };
6707 
6708 // -----------------------------------------------------------------------------
6709 /**
6710  * ForEachVoxel body for inside and outside unary voxel function of 4 non-const images
6711  */
6712 template <class T1, class T2, class T3, class T4,
6713  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
6714  class Domain = ForEachVoxelDomain::Foreground>
6715 struct QuaternaryForEachVoxelIfBody : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
6716 {
6717  GenericImage<T1> &im1;
6718  GenericImage<T2> &im2;
6719  GenericImage<T3> &im3;
6720  GenericImage<T4> &im4;
6721 
6722  /// Constructor
6724  GenericImage<T2> &im2,
6725  GenericImage<T3> &im3,
6726  GenericImage<T4> &im4,
6727  VoxelFunc &vf, OutsideFunc &of)
6728  :
6729  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4)
6730  {}
6731 
6732  /// Copy constructor
6734  :
6735  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
6736  {}
6737 
6738  /// Split constructor
6740  :
6741  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4)
6742  {}
6743 
6744  /// Process entire image
6745  void operator ()(const ImageAttributes &attr) const
6746  {
6747  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
6748  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
6749  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
6750  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
6751 
6752  const int T = (attr._dt ? attr._t : 1);
6753 
6754  for (int l = 0; l < T; ++l)
6755  for (int k = 0; k < attr._z; ++k)
6756  for (int j = 0; j < attr._y; ++j)
6757  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4) {
6758  if (Domain::IsInside(im4, i, j, k, l, p4)) {
6759  // const_cast such that voxel functions need only implement
6760  // non-const operator() which is required for parallel_reduce
6761  const_cast<QuaternaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4);
6762  } else const_cast<QuaternaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4);
6763  }
6764  }
6765 
6766  /// Process image region using linear index
6767  void operator ()(const blocked_range<int> &re) const
6768  {
6769  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
6770  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
6771  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
6772  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
6773 
6774  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
6775  if (Domain::IsInside(im4, idx, p4)) {
6776  // const_cast such that voxel functions need only implement
6777  // non-const operator() which is required for parallel_reduce
6778  const_cast<QuaternaryForEachVoxelIfBody *>(this)->_VoxelFunc (im4, idx, p1, p2, p3, p4);
6779  } else const_cast<QuaternaryForEachVoxelIfBody *>(this)->_OutsideFunc(im4, idx, p1, p2, p3, p4);
6780  }
6781  }
6782 
6783  /// Process 2D image region
6784  void operator ()(const blocked_range2d<int> &re) const
6785  {
6786  const int bi = re.cols().begin();
6787  const int bj = re.rows().begin();
6788  const int ei = re.cols().end();
6789  const int ej = re.rows().end();
6790 
6791  const int s1 = im4.GetX() - (ei - bi);
6792 
6793  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6794  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6795  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6796  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6797 
6798  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
6799  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
6800  if (Domain::IsInside(im4, i, j, this->_k, this->_l, p4)) {
6801  // const_cast such that voxel functions need only implement
6802  // non-const operator() which is required for parallel_reduce
6803  const_cast<QuaternaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4);
6804  } else const_cast<QuaternaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4);
6805  }
6806  }
6807 
6808  /// Process 3D image region
6809  void operator ()(const blocked_range3d<int> &re) const
6810  {
6811  const int bi = re.cols ().begin();
6812  const int bj = re.rows ().begin();
6813  const int bk = re.pages().begin();
6814  const int ei = re.cols ().end();
6815  const int ej = re.rows ().end();
6816  const int ek = re.pages().end();
6817 
6818  const int s1 = im4.GetX() - (ei - bi);
6819  const int s2 = (im4.GetY() - (ej - bj)) * im4.GetX();
6820 
6821  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
6822  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
6823  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
6824  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
6825 
6826  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2)
6827  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1)
6828  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1) {
6829  if (Domain::IsInside(im4, i, j, k, this->_l, p4)) {
6830  // const_cast such that voxel functions need only implement
6831  // non-const operator() which is required for parallel_reduce
6832  const_cast<QuaternaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4);
6833  } else const_cast<QuaternaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4);
6834  }
6835  }
6836 };
6837 
6838 // -----------------------------------------------------------------------------
6839 // ForEachVoxel
6840 // -----------------------------------------------------------------------------
6841 
6842 //
6843 // Image arguments by pointer
6844 //
6845 
6846 // -----------------------------------------------------------------------------
6847 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6848 void ForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6849 {
6850  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
6851  blocked_range<int> re(0, im4->GetNumberOfVoxels());
6852  body(re);
6853  vf.join(body._VoxelFunc);
6854 }
6855 
6856 // -----------------------------------------------------------------------------
6857 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6858 void ForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6859 {
6860  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6861  ForEachScalar(*im1, *im2, *im3, *im4, vf);
6862 }
6863 
6864 // -----------------------------------------------------------------------------
6865 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6866 void ForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6867 {
6868  if (im4->GetTSize()) {
6869  ForEachScalar(*im1, *im2, *im3, *im4, vf);
6870  } else {
6871  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
6872  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
6873  body(re);
6874  vf.join(body._VoxelFunc);
6875  }
6876 }
6877 
6878 // -----------------------------------------------------------------------------
6879 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6880 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6881 {
6882  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6883  ForEachVoxel(*im1, *im2, *im3, *im4, vf);
6884 }
6885 
6886 // -----------------------------------------------------------------------------
6887 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6888 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6889 {
6890  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
6891  body(attr);
6892  vf.join(body._VoxelFunc);
6893 }
6894 
6895 // -----------------------------------------------------------------------------
6896 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6897 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6898 {
6899  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6900  ForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
6901 }
6902 
6903 // -----------------------------------------------------------------------------
6904 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6905 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6906 {
6907  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
6908  body(re);
6909  vf.join(body._VoxelFunc);
6910 }
6911 
6912 // -----------------------------------------------------------------------------
6913 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6914 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6915 {
6916  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6917  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
6918 }
6919 
6920 // -----------------------------------------------------------------------------
6921 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6922 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6923 {
6924  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
6925  body(re);
6926  vf.join(body._VoxelFunc);
6927 }
6928 
6929 // -----------------------------------------------------------------------------
6930 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6931 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6932 {
6933  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6934  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
6935 }
6936 
6937 // -----------------------------------------------------------------------------
6938 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6939 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
6940 {
6941  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
6942  body(re);
6943  vf.join(body._VoxelFunc);
6944 }
6945 
6946 // -----------------------------------------------------------------------------
6947 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6948 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
6949 {
6950  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6951  ForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
6952 }
6953 
6954 //
6955 // Image arguments by reference
6956 //
6957 
6958 // -----------------------------------------------------------------------------
6959 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6960 void ForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6961 {
6962  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
6964  body(re);
6965  vf.join(body._VoxelFunc);
6966 }
6967 
6968 // -----------------------------------------------------------------------------
6969 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6970 void ForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6971 {
6972  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6973  ForEachScalar(im1, im2, im3, im4, vf);
6974 }
6975 
6976 // -----------------------------------------------------------------------------
6977 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6978 void ForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
6979 {
6980  if (im4.GetTSize()) {
6981  ForEachScalar(im1, im2, im3, im4, vf);
6982  } else {
6983  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
6984  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
6985  body(re);
6986  vf.join(body._VoxelFunc);
6987  }
6988 }
6989 
6990 // -----------------------------------------------------------------------------
6991 template <class T1, class T2, class T3, class T4, class VoxelFunc>
6992 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
6993 {
6994  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
6995  ForEachVoxel(im1, im2, im3, im4, vf);
6996 }
6997 
6998 // -----------------------------------------------------------------------------
6999 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7000 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7001 {
7002  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7003  body(attr);
7004  vf.join(body._VoxelFunc);
7005 }
7006 
7007 // -----------------------------------------------------------------------------
7008 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7009 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7010 {
7011  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7012  ForEachVoxel(attr, im1, im2, im3, im4, vf);
7013 }
7014 
7015 // -----------------------------------------------------------------------------
7016 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7017 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7018 {
7019  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7020  body(re);
7021  vf.join(body._VoxelFunc);
7022 }
7023 
7024 // -----------------------------------------------------------------------------
7025 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7026 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7027 {
7028  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7029  ForEachVoxel(re, im1, im2, im3, im4, vf);
7030 }
7031 
7032 // -----------------------------------------------------------------------------
7033 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7034 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7035 {
7036  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7037  body(re);
7038  vf.join(body._VoxelFunc);
7039 }
7040 
7041 // -----------------------------------------------------------------------------
7042 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7043 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7044 {
7045  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7046  ForEachVoxel(re, im1, im2, im3, im4, vf);
7047 }
7048 
7049 // -----------------------------------------------------------------------------
7050 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7051 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7052 {
7053  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7054  body(re);
7055  vf.join(body._VoxelFunc);
7056 }
7057 
7058 // -----------------------------------------------------------------------------
7059 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7060 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7061 {
7062  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7063  ForEachVoxel(re, im1, im2, im3, im4, vf);
7064 }
7065 
7066 // -----------------------------------------------------------------------------
7067 // ForEachVoxelIf
7068 // -----------------------------------------------------------------------------
7069 
7070 //
7071 // Image arguments by pointer
7072 //
7073 
7074 // -----------------------------------------------------------------------------
7075 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7076 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7077 {
7079  blocked_range<int> re(0, im4->GetNumberOfVoxels());
7080  body(re);
7081  vf.join(body._VoxelFunc);
7082  of.join(body._OutsideFunc);
7083 }
7084 
7085 // -----------------------------------------------------------------------------
7086 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7087 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7088 {
7089  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7090  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7091 }
7092 
7093 // -----------------------------------------------------------------------------
7094 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7095 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7096 {
7098  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7099 }
7100 
7101 // -----------------------------------------------------------------------------
7102 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7103 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7104 {
7105  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7106  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
7107 }
7108 
7109 // -----------------------------------------------------------------------------
7110 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7111 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7112 {
7113  if (im4->GetTSize()) {
7114  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7115  } else {
7117  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
7118  body(re);
7119  vf.join(body._VoxelFunc);
7120  of.join(body._OutsideFunc);
7121  }
7122 }
7123 
7124 // -----------------------------------------------------------------------------
7125 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7126 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7127 {
7128  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7129  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7130 }
7131 
7132 // -----------------------------------------------------------------------------
7133 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7134 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7135 {
7137  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7138 }
7139 
7140 // -----------------------------------------------------------------------------
7141 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7142 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7143 {
7144  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7145  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
7146 }
7147 
7148 // -----------------------------------------------------------------------------
7149 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7150 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7151 {
7153  body(attr);
7154  vf.join(body._VoxelFunc);
7155  of.join(body._OutsideFunc);
7156 }
7157 
7158 // -----------------------------------------------------------------------------
7159 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7160 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7161 {
7162  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7163  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
7164 }
7165 
7166 // -----------------------------------------------------------------------------
7167 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7168 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7169 {
7171  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
7172 }
7173 
7174 // -----------------------------------------------------------------------------
7175 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7176 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7177 {
7178  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7179  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
7180 }
7181 
7182 // -----------------------------------------------------------------------------
7183 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7184 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7185 {
7187  body(re);
7188  vf.join(body._VoxelFunc);
7189  of.join(body._OutsideFunc);
7190 }
7191 
7192 // -----------------------------------------------------------------------------
7193 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7194 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7195 {
7196  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7197  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7198 }
7199 
7200 // -----------------------------------------------------------------------------
7201 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7202 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7203 {
7205  body(re);
7206  vf.join(body._VoxelFunc);
7207  of.join(body._OutsideFunc);
7208 }
7209 
7210 // -----------------------------------------------------------------------------
7211 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7212 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7213 {
7214  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7215  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7216 }
7217 
7218 // -----------------------------------------------------------------------------
7219 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7220 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7221 {
7223  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7224 }
7225 
7226 // -----------------------------------------------------------------------------
7227 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7228 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7229 {
7230  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7231  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
7232 }
7233 
7234 // -----------------------------------------------------------------------------
7235 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7236 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7237 {
7239  body(re);
7240  vf.join(body._VoxelFunc);
7241  of.join(body._OutsideFunc);
7242 }
7243 
7244 // -----------------------------------------------------------------------------
7245 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7246 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7247 {
7248  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7249  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7250 }
7251 
7252 // -----------------------------------------------------------------------------
7253 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7254 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7255 {
7257  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7258 }
7259 
7260 // -----------------------------------------------------------------------------
7261 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7262 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7263 {
7264  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7265  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
7266 }
7267 
7268 //
7269 // Image arguments by reference
7270 //
7271 
7272 // -----------------------------------------------------------------------------
7273 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7274 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7275 {
7278  body(re);
7279  vf.join(body._VoxelFunc);
7280  of.join(body._OutsideFunc);
7281 }
7282 
7283 // -----------------------------------------------------------------------------
7284 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7285 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7286 {
7287  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7288  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
7289 }
7290 
7291 // -----------------------------------------------------------------------------
7292 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7293 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7294 {
7296  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
7297 }
7298 
7299 // -----------------------------------------------------------------------------
7300 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7301 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7302 {
7303  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7304  ForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
7305 }
7306 
7307 // -----------------------------------------------------------------------------
7308 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7309 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7310 {
7311  if (im4.GetTSize()) {
7312  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
7313  } else {
7315  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
7316  body(re);
7317  vf.join(body._VoxelFunc);
7318  of.join(body._OutsideFunc);
7319  }
7320 }
7321 
7322 // -----------------------------------------------------------------------------
7323 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7324 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7325 {
7326  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7327  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
7328 }
7329 
7330 // -----------------------------------------------------------------------------
7331 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7332 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7333 {
7335  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
7336 }
7337 
7338 // -----------------------------------------------------------------------------
7339 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7340 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7341 {
7342  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7343  ForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
7344 }
7345 
7346 // -----------------------------------------------------------------------------
7347 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7348 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7349 {
7351  body(attr);
7352  vf.join(body._VoxelFunc);
7353  of.join(body._OutsideFunc);
7354 }
7355 
7356 // -----------------------------------------------------------------------------
7357 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7358 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7359 {
7360  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7361  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
7362 }
7363 
7364 // -----------------------------------------------------------------------------
7365 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7366 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7367 {
7369  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
7370 }
7371 
7372 // -----------------------------------------------------------------------------
7373 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7374 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7375 {
7376  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7377  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
7378 }
7379 
7380 // -----------------------------------------------------------------------------
7381 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7382 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7383 {
7385  body(re);
7386  vf.join(body._VoxelFunc);
7387  of.join(body._OutsideFunc);
7388 }
7389 
7390 // -----------------------------------------------------------------------------
7391 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7392 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7393 {
7394  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7395  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
7396 }
7397 
7398 // -----------------------------------------------------------------------------
7399 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7400 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7401 {
7403  body(re);
7404  vf.join(body._VoxelFunc);
7405  of.join(body._OutsideFunc);
7406 }
7407 
7408 // -----------------------------------------------------------------------------
7409 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7410 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7411 {
7412  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7413  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
7414 }
7415 
7416 // -----------------------------------------------------------------------------
7417 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7418 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7419 {
7421  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
7422 }
7423 
7424 // -----------------------------------------------------------------------------
7425 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7426 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7427 {
7428  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7429  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
7430 }
7431 
7432 // -----------------------------------------------------------------------------
7433 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7434 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7435 {
7437  body(re);
7438  vf.join(body._VoxelFunc);
7439  of.join(body._OutsideFunc);
7440 }
7441 
7442 // -----------------------------------------------------------------------------
7443 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7444 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7445 {
7446  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7447  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
7448 }
7449 
7450 // -----------------------------------------------------------------------------
7451 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7452 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7453 {
7455  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
7456 }
7457 
7458 // -----------------------------------------------------------------------------
7459 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7460 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7461 {
7462  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7463  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
7464 }
7465 
7466 // -----------------------------------------------------------------------------
7467 // ParallelForEachVoxel
7468 // -----------------------------------------------------------------------------
7469 
7470 //
7471 // Image arguments by pointer
7472 //
7473 
7474 // -----------------------------------------------------------------------------
7475 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7476 void ParallelForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7477 {
7478  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
7479  blocked_range<int> re(0, im4->GetNumberOfVoxels());
7480  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7481  else parallel_for (re, body);
7482 }
7483 
7484 // -----------------------------------------------------------------------------
7485 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7486 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7487 {
7488  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7489  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
7490 }
7491 
7492 // -----------------------------------------------------------------------------
7493 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7494 void ParallelForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7495 {
7496  if (im4->GetTSize()) {
7497  ParallelForEachScalar(*im1, *im2, *im3, *im4, vf);
7498  } else {
7499  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
7500  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
7501  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7502  else parallel_for (re, body);
7503  }
7504 }
7505 
7506 // -----------------------------------------------------------------------------
7507 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7508 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7509 {
7510  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7511  ParallelForEachVoxel(*im1, *im2, *im3, *im4, vf);
7512 }
7513 
7514 // -----------------------------------------------------------------------------
7515 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7516 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7517 {
7518  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
7519  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
7520  if (VoxelFunc::IsReduction()) {
7521  if (attr._dt) {
7522  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
7523  } else {
7524  parallel_reduce(re, body);
7525  }
7526  vf.join(body._VoxelFunc);
7527  } else {
7528  if (attr._dt) {
7529  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
7530  } else {
7531  parallel_for(re, body);
7532  }
7533  }
7534 }
7535 
7536 // -----------------------------------------------------------------------------
7537 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7538 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7539 {
7540  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7541  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, vf);
7542 }
7543 
7544 // -----------------------------------------------------------------------------
7545 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7546 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7547 {
7548  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
7549  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7550  else parallel_for (re, body);
7551 }
7552 
7553 // -----------------------------------------------------------------------------
7554 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7555 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7556 {
7557  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7558  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
7559 }
7560 
7561 // -----------------------------------------------------------------------------
7562 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7563 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7564 {
7565  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
7566  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7567  else parallel_for (re, body);
7568 }
7569 
7570 // -----------------------------------------------------------------------------
7571 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7572 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7573 {
7574  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7575  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
7576 }
7577 
7578 // -----------------------------------------------------------------------------
7579 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7580 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7581 {
7582  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(*im1, *im2, *im3, *im4, vf);
7583  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7584  else parallel_for (re, body);
7585 }
7586 
7587 // -----------------------------------------------------------------------------
7588 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7589 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7590 {
7591  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7592  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, vf);
7593 }
7594 
7595 //
7596 // Image arguments by reference
7597 //
7598 
7599 // -----------------------------------------------------------------------------
7600 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7601 void ParallelForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7602 {
7603  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7605  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7606  else parallel_for (re, body);
7607 }
7608 
7609 // -----------------------------------------------------------------------------
7610 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7611 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7612 {
7613  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7614  ParallelForEachScalar(im1, im2, im3, im4, vf);
7615 }
7616 
7617 // -----------------------------------------------------------------------------
7618 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7619 void ParallelForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7620 {
7621  if (im4.GetTSize()) {
7622  ParallelForEachScalar(im1, im2, im3, im4, vf);
7623  } else {
7624  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7625  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
7626  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7627  else parallel_for (re, body);
7628  }
7629 }
7630 
7631 // -----------------------------------------------------------------------------
7632 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7633 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7634 {
7635  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7636  ParallelForEachVoxel(im1, im2, im3, im4, vf);
7637 }
7638 
7639 // -----------------------------------------------------------------------------
7640 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7641 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7642 {
7643  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7644  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
7645  if (VoxelFunc::IsReduction()) {
7646  if (attr._dt) {
7647  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
7648  } else {
7649  parallel_reduce(re, body);
7650  }
7651  vf.join(body._VoxelFunc);
7652  } else {
7653  if (attr._dt) {
7654  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
7655  } else {
7656  parallel_for(re, body);
7657  }
7658  }
7659 }
7660 
7661 // -----------------------------------------------------------------------------
7662 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7663 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7664 {
7665  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7666  ParallelForEachVoxel(attr, im1, im2, im3, im4, vf);
7667 }
7668 
7669 // -----------------------------------------------------------------------------
7670 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7671 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7672 {
7673  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7674  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7675  else parallel_for (re, body);
7676 }
7677 
7678 // -----------------------------------------------------------------------------
7679 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7680 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7681 {
7682  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7683  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
7684 }
7685 
7686 // -----------------------------------------------------------------------------
7687 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7688 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7689 {
7690  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7691  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7692  else parallel_for (re, body);
7693 }
7694 
7695 // -----------------------------------------------------------------------------
7696 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7697 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7698 {
7699  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7700  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
7701 }
7702 
7703 // -----------------------------------------------------------------------------
7704 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7705 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
7706 {
7707  QuaternaryForEachVoxelBody<T1, T2, T3, T4, VoxelFunc> body(im1, im2, im3, im4, vf);
7708  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7709  else parallel_for (re, body);
7710 }
7711 
7712 // -----------------------------------------------------------------------------
7713 template <class T1, class T2, class T3, class T4, class VoxelFunc>
7714 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7715 {
7716  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7717  ParallelForEachVoxel(re, im1, im2, im3, im4, vf);
7718 }
7719 
7720 // -----------------------------------------------------------------------------
7721 // ParallelForEachVoxelIf
7722 // -----------------------------------------------------------------------------
7723 
7724 //
7725 // Image arguments by pointer
7726 //
7727 
7728 // -----------------------------------------------------------------------------
7729 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7730 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7731 {
7733  blocked_range<int> re(0, im4->GetNumberOfVoxels());
7734  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7735  parallel_reduce(re, body);
7736  vf.join(body._VoxelFunc);
7737  of.join(body._OutsideFunc);
7738  } else {
7739  parallel_for(re, body);
7740  }
7741 }
7742 
7743 // -----------------------------------------------------------------------------
7744 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7745 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7746 {
7747  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7748  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7749 }
7750 
7751 // -----------------------------------------------------------------------------
7752 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7753 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7754 {
7756  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7757 }
7758 
7759 // -----------------------------------------------------------------------------
7760 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7761 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7762 {
7763  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7764  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, vf);
7765 }
7766 
7767 // -----------------------------------------------------------------------------
7768 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7769 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7770 {
7771  if (im4->GetTSize()) {
7772  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7773  } else {
7775  blocked_range<int> re(0, im4->GetNumberOfVoxels() / im4->GetT());
7776  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7777  parallel_reduce(re, body);
7778  vf.join(body._VoxelFunc);
7779  of.join(body._OutsideFunc);
7780  } else {
7781  parallel_for(re, body);
7782  }
7783  }
7784 }
7785 
7786 // -----------------------------------------------------------------------------
7787 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7788 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7789 {
7790  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7791  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7792 }
7793 
7794 // -----------------------------------------------------------------------------
7795 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7796 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7797 {
7799  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf, of);
7800 }
7801 
7802 // -----------------------------------------------------------------------------
7803 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7804 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7805 {
7806  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7807  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, vf);
7808 }
7809 
7810 // -----------------------------------------------------------------------------
7811 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7812 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7813 {
7815  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
7816  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7817  if (attr._dt) {
7818  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
7819  } else {
7820  parallel_reduce(re, body);
7821  }
7822  vf.join(body._VoxelFunc);
7823  of.join(body._OutsideFunc);
7824  } else {
7825  if (attr._dt) {
7826  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
7827  } else {
7828  parallel_for(re, body);
7829  }
7830  }
7831 }
7832 
7833 // -----------------------------------------------------------------------------
7834 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7835 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7836 {
7837  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7838  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
7839 }
7840 
7841 // -----------------------------------------------------------------------------
7842 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7843 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7844 {
7846  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf, of);
7847 }
7848 
7849 // -----------------------------------------------------------------------------
7850 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7851 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7852 {
7853  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7854  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, vf);
7855 }
7856 
7857 // -----------------------------------------------------------------------------
7858 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7859 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7860 {
7862  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7863  parallel_reduce(re, body);
7864  vf.join(body._VoxelFunc);
7865  of.join(body._OutsideFunc);
7866  } else {
7867  parallel_for(re, body);
7868  }
7869 }
7870 
7871 // -----------------------------------------------------------------------------
7872 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7873 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7874 {
7875  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7876  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7877 }
7878 
7879 // -----------------------------------------------------------------------------
7880 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7881 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7882 {
7884  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7885 }
7886 
7887 // -----------------------------------------------------------------------------
7888 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7889 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7890 {
7891  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7892  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
7893 }
7894 
7895 // -----------------------------------------------------------------------------
7896 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7897 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7898 {
7900  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7901  parallel_reduce(re, body);
7902  vf.join(body._VoxelFunc);
7903  of.join(body._OutsideFunc);
7904  } else {
7905  parallel_for(re, body);
7906  }
7907 }
7908 
7909 // -----------------------------------------------------------------------------
7910 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7911 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7912 {
7913  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7914  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7915 }
7916 
7917 // -----------------------------------------------------------------------------
7918 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7919 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7920 {
7922  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7923 }
7924 
7925 // -----------------------------------------------------------------------------
7926 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7927 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7928 {
7929  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7930  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
7931 }
7932 
7933 // -----------------------------------------------------------------------------
7934 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7935 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf, OutsideFunc &of)
7936 {
7938  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7939  parallel_reduce(re, body);
7940  vf.join(body._VoxelFunc);
7941  of.join(body._OutsideFunc);
7942  } else {
7943  parallel_for(re, body);
7944  }
7945 }
7946 
7947 // -----------------------------------------------------------------------------
7948 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7949 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7950 {
7951  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7952  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7953 }
7954 
7955 // -----------------------------------------------------------------------------
7956 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7957 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, VoxelFunc &vf)
7958 {
7960  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf, of);
7961 }
7962 
7963 // -----------------------------------------------------------------------------
7964 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
7965 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4)
7966 {
7967  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7968  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, vf);
7969 }
7970 
7971 //
7972 // Image arguments by reference
7973 //
7974 
7975 // -----------------------------------------------------------------------------
7976 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7977 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
7978 {
7981  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7982  parallel_reduce(re, body);
7983  vf.join(body._VoxelFunc);
7984  of.join(body._OutsideFunc);
7985  } else {
7986  parallel_for(re, body);
7987  }
7988 }
7989 
7990 // -----------------------------------------------------------------------------
7991 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
7992 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
7993 {
7994  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
7995  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
7996 }
7997 
7998 // -----------------------------------------------------------------------------
7999 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8000 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
8001 {
8003  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf, of);
8004 }
8005 
8006 // -----------------------------------------------------------------------------
8007 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8008 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8009 {
8010  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8011  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, vf);
8012 }
8013 
8014 // -----------------------------------------------------------------------------
8015 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8016 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
8017 {
8018  if (im4.GetTSize()) {
8019  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
8020  } else {
8022  blocked_range<int> re(0, im4.GetNumberOfVoxels() / im4.GetT());
8023  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8024  parallel_reduce(re, body);
8025  vf.join(body._VoxelFunc);
8026  of.join(body._OutsideFunc);
8027  } else {
8028  parallel_for(re, body);
8029  }
8030  }
8031 }
8032 
8033 // -----------------------------------------------------------------------------
8034 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8035 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8036 {
8037  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8038  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
8039 }
8040 
8041 // -----------------------------------------------------------------------------
8042 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8043 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
8044 {
8046  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf, of);
8047 }
8048 
8049 // -----------------------------------------------------------------------------
8050 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8051 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8052 {
8053  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8054  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, vf);
8055 }
8056 
8057 // -----------------------------------------------------------------------------
8058 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8059 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
8060 {
8062  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
8063  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8064  if (attr._dt) {
8065  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
8066  } else {
8067  parallel_reduce(re, body);
8068  }
8069  vf.join(body._VoxelFunc);
8070  of.join(body._OutsideFunc);
8071  } else {
8072  if (attr._dt) {
8073  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
8074  } else {
8075  parallel_for(re, body);
8076  }
8077  }
8078 }
8079 
8080 // -----------------------------------------------------------------------------
8081 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8082 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8083 {
8084  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8085  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
8086 }
8087 
8088 // -----------------------------------------------------------------------------
8089 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8090 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
8091 {
8093  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf, of);
8094 }
8095 
8096 // -----------------------------------------------------------------------------
8097 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8098 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8099 {
8100  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8101  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, vf);
8102 }
8103 
8104 // -----------------------------------------------------------------------------
8105 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8106 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
8107 {
8109  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8110  parallel_reduce(re, body);
8111  vf.join(body._VoxelFunc);
8112  of.join(body._OutsideFunc);
8113  } else {
8114  parallel_for(re, body);
8115  }
8116 }
8117 
8118 // -----------------------------------------------------------------------------
8119 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8120 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8121 {
8122  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8123  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
8124 }
8125 
8126 // -----------------------------------------------------------------------------
8127 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8128 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
8129 {
8131  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
8132 }
8133 
8134 // -----------------------------------------------------------------------------
8135 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8136 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8137 {
8138  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8139  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
8140 }
8141 
8142 // -----------------------------------------------------------------------------
8143 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8144 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
8145 {
8147  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8148  parallel_reduce(re, body);
8149  vf.join(body._VoxelFunc);
8150  of.join(body._OutsideFunc);
8151  } else {
8152  parallel_for(re, body);
8153  }
8154 }
8155 
8156 // -----------------------------------------------------------------------------
8157 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8158 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8159 {
8160  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8161  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
8162 }
8163 
8164 // -----------------------------------------------------------------------------
8165 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8166 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
8167 {
8169  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
8170 }
8171 
8172 // -----------------------------------------------------------------------------
8173 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8174 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8175 {
8176  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8177  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
8178 }
8179 
8180 // -----------------------------------------------------------------------------
8181 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8182 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf, OutsideFunc &of)
8183 {
8185  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8186  parallel_reduce(re, body);
8187  vf.join(body._VoxelFunc);
8188  of.join(body._OutsideFunc);
8189  } else {
8190  parallel_for(re, body);
8191  }
8192 }
8193 
8194 // -----------------------------------------------------------------------------
8195 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc, class OutsideFunc>
8196 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8197 {
8198  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8199  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
8200 }
8201 
8202 // -----------------------------------------------------------------------------
8203 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8204 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, VoxelFunc &vf)
8205 {
8207  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf, of);
8208 }
8209 
8210 // -----------------------------------------------------------------------------
8211 template <class Domain, class T1, class T2, class T3, class T4, class VoxelFunc>
8212 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4)
8213 {
8214  if (VoxelFunc::IsReduction()) _foreachquaternaryvoxelfunction_must_not_be_reduction();
8215  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, vf);
8216 }
8217 
8218 
8219 } // namespace mirtk
8220 
8221 #endif
QuaternaryForEachVoxelBody_Const(QuaternaryForEachVoxelBody_Const &o, split s)
Split constructor.
double _dt
Voxel t-dimensions (in ms)
QuaternaryForEachVoxelBody_1Const(QuaternaryForEachVoxelBody_1Const &o, split s)
Split constructor.
QuaternaryForEachVoxelIfBody_1Const(const QuaternaryForEachVoxelIfBody_1Const &o)
Copy constructor.
QuaternaryForEachVoxelBody_1Const(const QuaternaryForEachVoxelBody_1Const &o)
Copy constructor.
QuaternaryForEachVoxelBody_2Const(QuaternaryForEachVoxelBody_2Const &o, split s)
Split constructor.
Dummy type used to distinguish split constructor from copy constructor.
Definition: Parallel.h:143
QuaternaryForEachVoxelBody_2Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf)
Constructor.
QuaternaryForEachVoxelIfBody_Const(const QuaternaryForEachVoxelIfBody_Const &o)
Copy constructor.
QuaternaryForEachVoxelBody(QuaternaryForEachVoxelBody &o, split s)
Split constructor.
Two-dimensional range.
Definition: Parallel.h:168
bool IsEmpty() const
Whether image is uninitialized.
Definition: BaseImage.h:1283
void operator()(const ImageAttributes &attr) const
Process entire image.
QuaternaryForEachVoxelIfBody_3Const(QuaternaryForEachVoxelIfBody_3Const &o, split s)
Split constructor.
QuaternaryForEachVoxelIfBody_Const(QuaternaryForEachVoxelIfBody_Const &o, split s)
Split constructor.
QuaternaryForEachVoxelIfBody_2Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf, OutsideFunc &of)
Constructor.
int _y
Image y-dimension (in voxels)
QuaternaryForEachVoxelIfBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf, OutsideFunc &of)
Constructor.
One-dimensional range.
Definition: Parallel.h:155
VoxelFunc _VoxelFunc
Functor executed for each voxel.
QuaternaryForEachVoxelIfBody(const QuaternaryForEachVoxelIfBody &o)
Copy constructor.
QuaternaryForEachVoxelBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf)
Constructor.
QuaternaryForEachVoxelBody_2Const(const QuaternaryForEachVoxelBody_2Const &o)
Copy constructor.
QuaternaryForEachVoxelIfBody_2Const(const QuaternaryForEachVoxelIfBody_2Const &o)
Copy constructor.
QuaternaryForEachVoxelIfBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, const GenericImage< T4 > &im4, VoxelFunc &vf, OutsideFunc &of)
Constructor.
Definition: IOConfig.h:41
VoxelType * GetPointerToVoxels(int=0, int=0, int=0, int=0)
Definition: GenericImage.h:849
int GetX() const
Returns the number of voxels in the x-direction.
Definition: BaseImage.h:904
int _z
Image z-dimension (in voxels)
int _l
Indices for fixed dimensions.
QuaternaryForEachVoxelIfBody_3Const(const QuaternaryForEachVoxelIfBody_3Const &o)
Copy constructor.
QuaternaryForEachVoxelBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, const GenericImage< T4 > &im4, VoxelFunc &vf)
Constructor.
QuaternaryForEachVoxelIfBody_3Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf, OutsideFunc &of)
Constructor.
int _t
Image t-dimension (in voxels)
QuaternaryForEachVoxelBody_3Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf)
Constructor.
int GetT() const
Returns the number of voxels in the t-direction.
Definition: BaseImage.h:922
int GetY() const
Returns the number of voxels in the y-direction.
Definition: BaseImage.h:910
QuaternaryForEachVoxelIfBody_2Const(QuaternaryForEachVoxelIfBody_2Const &o, split s)
Split constructor.
QuaternaryForEachVoxelIfBody(QuaternaryForEachVoxelIfBody &o, split s)
Split constructor.
Three-dimensional range.
Definition: Parallel.h:197
int GetNumberOfVoxels() const
Definition: BaseImage.h:1741
QuaternaryForEachVoxelBody_3Const(const QuaternaryForEachVoxelBody_3Const &o)
Copy constructor.
OutsideFunc _OutsideFunc
Functor executed for each background voxel.
QuaternaryForEachVoxelIfBody_1Const(QuaternaryForEachVoxelIfBody_1Const &o, split s)
Split constructor.
double GetTSize() const
Returns the size of a voxel in the t-direction.
Definition: BaseImage.h:970
QuaternaryForEachVoxelBody_3Const(QuaternaryForEachVoxelBody_3Const &o, split s)
Split constructor.
QuaternaryForEachVoxelBody(const QuaternaryForEachVoxelBody &o)
Copy constructor.
int _x
Image x-dimension (in voxels)
QuaternaryForEachVoxelIfBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf, OutsideFunc &of)
Constructor.
void parallel_reduce(const Range &range, Body &body)
parallel_reduce dummy template function which executes the body serially
Definition: Parallel.h:238
QuaternaryForEachVoxelBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, VoxelFunc &vf)
Constructor.
QuaternaryForEachVoxelBody_Const(const QuaternaryForEachVoxelBody_Const &o)
Copy constructor.
void parallel_for(const Range &range, const Body &body)
parallel_for dummy template function which executes the body serially
Definition: Parallel.h:232