ForEachQuinaryVoxelFunction.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_ForEachQuinaryVoxelFunction_H
31 #define MIRTK_ForEachQuinaryVoxelFunction_H
32 
33 #include "mirtk/Stream.h"
34 #include "mirtk/VoxelFunction.h"
35 
36 
37 namespace mirtk {
38 
39 
40 inline void _foreachquinaryvoxelfunction_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 // 5 const images
50 // =============================================================================
51 
52 // -----------------------------------------------------------------------------
53 /**
54  * ForEachVoxel body for voxel function of 5 const images
55  */
56 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
58 {
59  const GenericImage<T1> &im1;
60  const GenericImage<T2> &im2;
61  const GenericImage<T3> &im3;
62  const GenericImage<T4> &im4;
63  const GenericImage<T5> &im5;
64 
65  /// Constructor
67  const GenericImage<T2> &im2,
68  const GenericImage<T3> &im3,
69  const GenericImage<T4> &im4,
70  const GenericImage<T5> &im5,
71  VoxelFunc &vf)
72  :
73  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
74  {}
75 
76  /// Copy constructor
78  :
79  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
80  {}
81 
82  /// Split constructor
84  :
85  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
86  {}
87 
88  /// Process entire image
89  void operator ()(const ImageAttributes &attr) const
90  {
91  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
92  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
93  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
94  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
95  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
96 
97  const int T = (attr._dt ? attr._t : 1);
98 
99  for (int l = 0; l < T; ++l)
100  for (int k = 0; k < attr._z; ++k)
101  for (int j = 0; j < attr._y; ++j)
102  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
103  // const_cast such that voxel functions need only implement
104  // non-const operator() which is required for parallel_reduce
105  const_cast<QuinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4, p5);
106  }
107  }
108 
109  /// Process image region using linear index
110  void operator ()(const blocked_range<int> &re) const
111  {
112  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
113  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
114  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
115  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
116  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
117 
118  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
119  // const_cast such that voxel functions need only implement
120  // non-const operator() which is required for parallel_reduce
121  const_cast<QuinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(im5, idx, p1, p2, p3, p4, p5);
122  }
123  }
124 
125  /// Process 2D image region
126  void operator ()(const blocked_range2d<int> &re) const
127  {
128  const int bi = re.cols().begin();
129  const int bj = re.rows().begin();
130  const int ei = re.cols().end();
131  const int ej = re.rows().end();
132 
133  const int s1 = im5.GetX() - (ei - bi);
134 
135  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
136  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
137  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
138  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
139  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
140 
141  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
142  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
143  // const_cast such that voxel functions need only implement
144  // non-const operator() which is required for parallel_reduce
145  const_cast<QuinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
146  }
147  }
148 
149  /// Process 3D image region
150  void operator ()(const blocked_range3d<int> &re) const
151  {
152  const int bi = re.cols ().begin();
153  const int bj = re.rows ().begin();
154  const int bk = re.pages().begin();
155  const int ei = re.cols ().end();
156  const int ej = re.rows ().end();
157  const int ek = re.pages().end();
158 
159  const int s1 = im5.GetX() - (ei - bi);
160  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
161 
162  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
163  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
164  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
165  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
166  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
167 
168  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
169  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
170  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
171  // const_cast such that voxel functions need only implement
172  // non-const operator() which is required for parallel_reduce
173  const_cast<QuinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
174  }
175  }
176 };
177 
178 // -----------------------------------------------------------------------------
179 /**
180  * ForEachVoxel body for inside and outside unary voxel function of 5 const images
181  */
182 template <class T1, class T2, class T3, class T4, class T5,
183  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
184  class Domain = ForEachVoxelDomain::Foreground>
185 struct QuinaryForEachVoxelIfBody_Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
186 {
187  const GenericImage<T1> &im1;
188  const GenericImage<T2> &im2;
189  const GenericImage<T3> &im3;
190  const GenericImage<T4> &im4;
191  const GenericImage<T5> &im5;
192 
193  /// Constructor
195  const GenericImage<T2> &im2,
196  const GenericImage<T3> &im3,
197  const GenericImage<T4> &im4,
198  const GenericImage<T5> &im5,
199  VoxelFunc &vf, OutsideFunc &of)
200  :
201  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
202  {}
203 
204  /// Copy constructor
206  :
207  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
208  {}
209 
210  /// Split constructor
212  :
213  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
214  {}
215 
216  /// Process entire image
217  void operator ()(const ImageAttributes &attr) const
218  {
219  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
220  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
221  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
222  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
223  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
224 
225  const int T = (attr._dt ? attr._t : 1);
226 
227  for (int l = 0; l < T; ++l)
228  for (int k = 0; k < attr._z; ++k)
229  for (int j = 0; j < attr._y; ++j)
230  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
231  if (Domain::IsInside(im5, i, j, k, l, p5)) {
232  // const_cast such that voxel functions need only implement
233  // non-const operator() which is required for parallel_reduce
234  const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4, p5);
235  } else const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4, p5);
236  }
237  }
238 
239  /// Process image region using linear index
240  void operator ()(const blocked_range<int> &re) const
241  {
242  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
243  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
244  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
245  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
246  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
247 
248  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
249  if (Domain::IsInside(im5, idx, p5)) {
250  // const_cast such that voxel functions need only implement
251  // non-const operator() which is required for parallel_reduce
252  const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (im5, idx, p1, p2, p3, p4, p5);
253  } else const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(im5, idx, p1, p2, p3, p4, p5);
254  }
255  }
256 
257  /// Process 2D image region
258  void operator ()(const blocked_range2d<int> &re) const
259  {
260  const int bi = re.cols().begin();
261  const int bj = re.rows().begin();
262  const int ei = re.cols().end();
263  const int ej = re.rows().end();
264 
265  const int s1 = im5.GetX() - (ei - bi);
266 
267  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
268  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
269  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
270  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
271  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
272 
273  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
274  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
275  if (Domain::IsInside(im5, i, j, this->_k, this->_l, p5)) {
276  // const_cast such that voxel functions need only implement
277  // non-const operator() which is required for parallel_reduce
278  const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
279  } else const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
280  }
281  }
282 
283  /// Process 3D image region
284  void operator ()(const blocked_range3d<int> &re) const
285  {
286  const int bi = re.cols ().begin();
287  const int bj = re.rows ().begin();
288  const int bk = re.pages().begin();
289  const int ei = re.cols ().end();
290  const int ej = re.rows ().end();
291  const int ek = re.pages().end();
292 
293  const int s1 = im5.GetX() - (ei - bi);
294  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
295 
296  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
297  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
298  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
299  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
300  const T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
301 
302  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
303  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
304  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
305  if (Domain::IsInside(im5, i, j, k, this->_l, p5)) {
306  // const_cast such that voxel functions need only implement
307  // non-const operator() which is required for parallel_reduce
308  const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4, p5);
309  } else const_cast<QuinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
310  }
311  }
312 };
313 
314 // -----------------------------------------------------------------------------
315 // ForEachVoxel
316 // -----------------------------------------------------------------------------
317 
318 //
319 // Image arguments by pointer
320 //
321 
322 // -----------------------------------------------------------------------------
323 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
324 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
325 {
326  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
328  body(re);
329  vf.join(body._VoxelFunc);
330 }
331 
332 // -----------------------------------------------------------------------------
333 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
334 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
335 {
336  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
337  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
338 }
339 
340 // -----------------------------------------------------------------------------
341 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
342 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
343 {
344  if (im5->GetTSize()) {
345  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
346  } else {
347  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
348  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
349  body(re);
350  vf.join(body._VoxelFunc);
351  }
352 }
353 
354 // -----------------------------------------------------------------------------
355 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
356 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
357 {
358  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
359  ForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
360 }
361 
362 // -----------------------------------------------------------------------------
363 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
364 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
365 {
366  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
367  body(attr);
368  vf.join(body._VoxelFunc);
369 }
370 
371 // -----------------------------------------------------------------------------
372 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
373 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
374 {
375  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
376  ForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
377 }
378 
379 // -----------------------------------------------------------------------------
380 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
381 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
382 {
383  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
384  body(re);
385  vf.join(body._VoxelFunc);
386 }
387 
388 // -----------------------------------------------------------------------------
389 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
390 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, const GenericImage<T5> *im5)
391 {
392  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
393  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
394 }
395 
396 // -----------------------------------------------------------------------------
397 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
398 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
399 {
400  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
401  body(re);
402  vf.join(body._VoxelFunc);
403 }
404 
405 // -----------------------------------------------------------------------------
406 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
407 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, const GenericImage<T5> *im5)
408 {
409  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
410  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
411 }
412 
413 // -----------------------------------------------------------------------------
414 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
415 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
416 {
417  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
418  body(re);
419  vf.join(body._VoxelFunc);
420 }
421 
422 // -----------------------------------------------------------------------------
423 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
424 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, const GenericImage<T5> *im5)
425 {
426  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
427  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
428 }
429 
430 //
431 // Image arguments by reference
432 //
433 
434 // -----------------------------------------------------------------------------
435 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
436 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
437 {
438  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
440  body(re);
441  vf.join(body._VoxelFunc);
442 }
443 
444 // -----------------------------------------------------------------------------
445 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
446 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
447 {
448  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
449  ForEachScalar(im1, im2, im3, im4, im5, vf);
450 }
451 
452 // -----------------------------------------------------------------------------
453 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
454 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
455 {
456  if (im5.GetTSize()) {
457  ForEachScalar(im1, im2, im3, im4, im5, vf);
458  } else {
459  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
460  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
461  body(re);
462  vf.join(body._VoxelFunc);
463  }
464 }
465 
466 // -----------------------------------------------------------------------------
467 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
468 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
469 {
470  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
471  ForEachVoxel(im1, im2, im3, im4, im5, vf);
472 }
473 
474 // -----------------------------------------------------------------------------
475 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
476 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
477 {
478  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
479  body(attr);
480  vf.join(body._VoxelFunc);
481 }
482 
483 // -----------------------------------------------------------------------------
484 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
485 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
486 {
487  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
488  ForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
489 }
490 
491 // -----------------------------------------------------------------------------
492 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
493 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
494 {
495  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
496  body(re);
497  vf.join(body._VoxelFunc);
498 }
499 
500 // -----------------------------------------------------------------------------
501 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
502 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, const GenericImage<T5> &im5)
503 {
504  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
505  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
506 }
507 
508 // -----------------------------------------------------------------------------
509 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
510 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
511 {
512  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
513  body(re);
514  vf.join(body._VoxelFunc);
515 }
516 
517 // -----------------------------------------------------------------------------
518 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
519 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, const GenericImage<T5> &im5)
520 {
521  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
522  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
523 }
524 
525 // -----------------------------------------------------------------------------
526 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
527 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
528 {
529  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
530  body(re);
531  vf.join(body._VoxelFunc);
532 }
533 
534 // -----------------------------------------------------------------------------
535 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
536 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, const GenericImage<T5> &im5)
537 {
538  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
539  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
540 }
541 
542 // -----------------------------------------------------------------------------
543 // ForEachVoxelIf
544 // -----------------------------------------------------------------------------
545 
546 //
547 // Image arguments by pointer
548 //
549 
550 // -----------------------------------------------------------------------------
551 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
552 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
553 {
556  body(re);
557  vf.join(body._VoxelFunc);
558  of.join(body._OutsideFunc);
559 }
560 
561 // -----------------------------------------------------------------------------
562 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
563 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
564 {
565  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
566  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
567 }
568 
569 // -----------------------------------------------------------------------------
570 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
571 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
572 {
574  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
575 }
576 
577 // -----------------------------------------------------------------------------
578 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
579 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
580 {
581  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
582  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
583 }
584 
585 // -----------------------------------------------------------------------------
586 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
587 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
588 {
589  if (im5->GetTSize()) {
590  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
591  } else {
593  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
594  body(re);
595  vf.join(body._VoxelFunc);
596  of.join(body._OutsideFunc);
597  }
598 }
599 
600 // -----------------------------------------------------------------------------
601 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
602 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
603 {
604  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
605  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
606 }
607 
608 // -----------------------------------------------------------------------------
609 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
610 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
611 {
613  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
614 }
615 
616 // -----------------------------------------------------------------------------
617 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
618 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
619 {
620  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
621  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
622 }
623 
624 // -----------------------------------------------------------------------------
625 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
626 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
627 {
629  body(attr);
630  vf.join(body._VoxelFunc);
631  of.join(body._OutsideFunc);
632 }
633 
634 // -----------------------------------------------------------------------------
635 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
636 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, const GenericImage<T5> *im5)
637 {
638  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
639  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
640 }
641 
642 // -----------------------------------------------------------------------------
643 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
644 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
645 {
647  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
648 }
649 
650 // -----------------------------------------------------------------------------
651 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
652 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
653 {
654  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
655  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
656 }
657 
658 // -----------------------------------------------------------------------------
659 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
660 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
661 {
663  body(re);
664  vf.join(body._VoxelFunc);
665  of.join(body._OutsideFunc);
666 }
667 
668 // -----------------------------------------------------------------------------
669 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
670 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, const GenericImage<T5> *im5)
671 {
672  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
673  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
674 }
675 
676 // -----------------------------------------------------------------------------
677 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
678 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
679 {
681  body(re);
682  vf.join(body._VoxelFunc);
683  of.join(body._OutsideFunc);
684 }
685 
686 // -----------------------------------------------------------------------------
687 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
688 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, const GenericImage<T5> *im5)
689 {
690  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
691  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
692 }
693 
694 // -----------------------------------------------------------------------------
695 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
696 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
697 {
699  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
700 }
701 
702 // -----------------------------------------------------------------------------
703 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
704 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, const GenericImage<T5> *im5)
705 {
706  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
707  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
708 }
709 
710 // -----------------------------------------------------------------------------
711 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
712 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
713 {
715  body(re);
716  vf.join(body._VoxelFunc);
717  of.join(body._OutsideFunc);
718 }
719 
720 // -----------------------------------------------------------------------------
721 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
722 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, const GenericImage<T5> *im5)
723 {
724  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
725  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
726 }
727 
728 // -----------------------------------------------------------------------------
729 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
730 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
731 {
733  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
734 }
735 
736 // -----------------------------------------------------------------------------
737 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
738 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, const GenericImage<T5> *im5)
739 {
740  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
741  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
742 }
743 
744 //
745 // Image arguments by reference
746 //
747 
748 // -----------------------------------------------------------------------------
749 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
750 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
751 {
754  body(re);
755  vf.join(body._VoxelFunc);
756  of.join(body._OutsideFunc);
757 }
758 
759 // -----------------------------------------------------------------------------
760 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
761 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
762 {
763  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
764  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
765 }
766 
767 // -----------------------------------------------------------------------------
768 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
769 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
770 {
772  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
773 }
774 
775 // -----------------------------------------------------------------------------
776 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
777 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
778 {
779  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
780  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
781 }
782 
783 // -----------------------------------------------------------------------------
784 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
785 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
786 {
787  if (im5.GetTSize()) {
788  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
789  } else {
791  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
792  body(re);
793  vf.join(body._VoxelFunc);
794  of.join(body._OutsideFunc);
795  }
796 }
797 
798 // -----------------------------------------------------------------------------
799 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
800 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
801 {
802  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
803  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
804 }
805 
806 // -----------------------------------------------------------------------------
807 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
808 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
809 {
811  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
812 }
813 
814 // -----------------------------------------------------------------------------
815 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
816 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
817 {
818  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
819  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
820 }
821 
822 // -----------------------------------------------------------------------------
823 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
824 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
825 {
827  body(attr);
828  vf.join(body._VoxelFunc);
829  of.join(body._OutsideFunc);
830 }
831 
832 // -----------------------------------------------------------------------------
833 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
834 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, const GenericImage<T5> &im5)
835 {
836  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
837  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
838 }
839 
840 // -----------------------------------------------------------------------------
841 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
842 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
843 {
845  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
846 }
847 
848 // -----------------------------------------------------------------------------
849 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
850 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
851 {
852  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
853  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
854 }
855 
856 // -----------------------------------------------------------------------------
857 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
858 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
859 {
861  body(re);
862  vf.join(body._VoxelFunc);
863  of.join(body._OutsideFunc);
864 }
865 
866 // -----------------------------------------------------------------------------
867 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
868 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, const GenericImage<T5> &im5)
869 {
870  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
871  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
872 }
873 
874 // -----------------------------------------------------------------------------
875 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
876 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
877 {
879  body(re);
880  vf.join(body._VoxelFunc);
881  of.join(body._OutsideFunc);
882 }
883 
884 // -----------------------------------------------------------------------------
885 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
886 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, const GenericImage<T5> &im5)
887 {
888  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
889  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
890 }
891 
892 // -----------------------------------------------------------------------------
893 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
894 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
895 {
897  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
898 }
899 
900 // -----------------------------------------------------------------------------
901 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
902 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, const GenericImage<T5> &im5)
903 {
904  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
905  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
906 }
907 
908 // -----------------------------------------------------------------------------
909 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
910 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
911 {
913  body(re);
914  vf.join(body._VoxelFunc);
915  of.join(body._OutsideFunc);
916 }
917 
918 // -----------------------------------------------------------------------------
919 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
920 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, const GenericImage<T5> &im5)
921 {
922  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
923  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
924 }
925 
926 // -----------------------------------------------------------------------------
927 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
928 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
929 {
931  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
932 }
933 
934 // -----------------------------------------------------------------------------
935 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
936 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, const GenericImage<T5> &im5)
937 {
938  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
939  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
940 }
941 
942 // -----------------------------------------------------------------------------
943 // ParallelForEachVoxel
944 // -----------------------------------------------------------------------------
945 
946 //
947 // Image arguments by pointer
948 //
949 
950 // -----------------------------------------------------------------------------
951 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
952 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
953 {
954  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
956  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
957  else parallel_for (re, body);
958 }
959 
960 // -----------------------------------------------------------------------------
961 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
962 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
963 {
964  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
965  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
966 }
967 
968 // -----------------------------------------------------------------------------
969 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
970 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
971 {
972  if (im5->GetTSize()) {
973  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
974  } else {
975  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
976  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
977  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
978  else parallel_for (re, body);
979  }
980 }
981 
982 // -----------------------------------------------------------------------------
983 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
984 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
985 {
986  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
987  ParallelForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
988 }
989 
990 // -----------------------------------------------------------------------------
991 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
992 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
993 {
994  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
995  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
996  if (VoxelFunc::IsReduction()) {
997  if (attr._dt) {
998  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
999  } else {
1000  parallel_reduce(re, body);
1001  }
1002  vf.join(body._VoxelFunc);
1003  } else {
1004  if (attr._dt) {
1005  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1006  } else {
1007  parallel_for(re, body);
1008  }
1009  }
1010 }
1011 
1012 // -----------------------------------------------------------------------------
1013 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1014 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
1015 {
1016  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1017  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
1018 }
1019 
1020 // -----------------------------------------------------------------------------
1021 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1022 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1023 {
1024  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
1025  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1026  else parallel_for (re, body);
1027 }
1028 
1029 // -----------------------------------------------------------------------------
1030 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1031 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, const GenericImage<T5> *im5)
1032 {
1033  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1034  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
1035 }
1036 
1037 // -----------------------------------------------------------------------------
1038 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1039 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1040 {
1041  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
1042  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1043  else parallel_for (re, body);
1044 }
1045 
1046 // -----------------------------------------------------------------------------
1047 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1048 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, const GenericImage<T5> *im5)
1049 {
1050  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1051  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
1052 }
1053 
1054 // -----------------------------------------------------------------------------
1055 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1056 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1057 {
1058  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
1059  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1060  else parallel_for (re, body);
1061 }
1062 
1063 // -----------------------------------------------------------------------------
1064 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1065 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, const GenericImage<T5> *im5)
1066 {
1067  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1068  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
1069 }
1070 
1071 //
1072 // Image arguments by reference
1073 //
1074 
1075 // -----------------------------------------------------------------------------
1076 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1077 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1078 {
1079  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
1081  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1082  else parallel_for (re, body);
1083 }
1084 
1085 // -----------------------------------------------------------------------------
1086 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1087 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1088 {
1089  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1090  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
1091 }
1092 
1093 // -----------------------------------------------------------------------------
1094 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1095 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1096 {
1097  if (im5.GetTSize()) {
1098  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
1099  } else {
1100  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
1101  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
1102  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1103  else parallel_for (re, body);
1104  }
1105 }
1106 
1107 // -----------------------------------------------------------------------------
1108 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1109 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1110 {
1111  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1112  ParallelForEachVoxel(im1, im2, im3, im4, im5, vf);
1113 }
1114 
1115 // -----------------------------------------------------------------------------
1116 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1117 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1118 {
1119  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
1120  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1121  if (VoxelFunc::IsReduction()) {
1122  if (attr._dt) {
1123  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1124  } else {
1125  parallel_reduce(re, body);
1126  }
1127  vf.join(body._VoxelFunc);
1128  } else {
1129  if (attr._dt) {
1130  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1131  } else {
1132  parallel_for(re, body);
1133  }
1134  }
1135 }
1136 
1137 // -----------------------------------------------------------------------------
1138 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1139 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1140 {
1141  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1142  ParallelForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
1143 }
1144 
1145 // -----------------------------------------------------------------------------
1146 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1147 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1148 {
1149  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
1150  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1151  else parallel_for (re, body);
1152 }
1153 
1154 // -----------------------------------------------------------------------------
1155 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1156 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, const GenericImage<T5> &im5)
1157 {
1158  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1159  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
1160 }
1161 
1162 // -----------------------------------------------------------------------------
1163 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1164 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1165 {
1166  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
1167  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1168  else parallel_for (re, body);
1169 }
1170 
1171 // -----------------------------------------------------------------------------
1172 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1173 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, const GenericImage<T5> &im5)
1174 {
1175  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1176  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
1177 }
1178 
1179 // -----------------------------------------------------------------------------
1180 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1181 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1182 {
1183  QuinaryForEachVoxelBody_Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
1184  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1185  else parallel_for (re, body);
1186 }
1187 
1188 // -----------------------------------------------------------------------------
1189 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1190 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, const GenericImage<T5> &im5)
1191 {
1192  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1193  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
1194 }
1195 
1196 // -----------------------------------------------------------------------------
1197 // ParallelForEachVoxelIf
1198 // -----------------------------------------------------------------------------
1199 
1200 //
1201 // Image arguments by pointer
1202 //
1203 
1204 // -----------------------------------------------------------------------------
1205 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1206 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
1207 {
1209  blocked_range<int> re(0, im5->GetNumberOfVoxels());
1210  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1211  parallel_reduce(re, body);
1212  vf.join(body._VoxelFunc);
1213  of.join(body._OutsideFunc);
1214  } else {
1215  parallel_for(re, body);
1216  }
1217 }
1218 
1219 // -----------------------------------------------------------------------------
1220 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1221 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
1222 {
1223  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1224  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
1225 }
1226 
1227 // -----------------------------------------------------------------------------
1228 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1229 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1230 {
1232  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
1233 }
1234 
1235 // -----------------------------------------------------------------------------
1236 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1237 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
1238 {
1239  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1240  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
1241 }
1242 
1243 // -----------------------------------------------------------------------------
1244 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1245 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
1246 {
1247  if (im5->GetTSize()) {
1248  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
1249  } else {
1251  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
1252  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1253  parallel_reduce(re, body);
1254  vf.join(body._VoxelFunc);
1255  of.join(body._OutsideFunc);
1256  } else {
1257  parallel_for(re, body);
1258  }
1259  }
1260 }
1261 
1262 // -----------------------------------------------------------------------------
1263 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1264 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
1265 {
1266  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1267  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
1268 }
1269 
1270 // -----------------------------------------------------------------------------
1271 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1272 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1273 {
1275  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
1276 }
1277 
1278 // -----------------------------------------------------------------------------
1279 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1280 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
1281 {
1282  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1283  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
1284 }
1285 
1286 // -----------------------------------------------------------------------------
1287 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1288 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
1289 {
1291  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1292  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1293  if (attr._dt) {
1294  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1295  } else {
1296  parallel_reduce(re, body);
1297  }
1298  vf.join(body._VoxelFunc);
1299  of.join(body._OutsideFunc);
1300  } else {
1301  if (attr._dt) {
1302  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1303  } else {
1304  parallel_for(re, body);
1305  }
1306  }
1307 }
1308 
1309 // -----------------------------------------------------------------------------
1310 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1311 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, const GenericImage<T5> *im5)
1312 {
1313  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1314  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
1315 }
1316 
1317 // -----------------------------------------------------------------------------
1318 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1319 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1320 {
1322  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
1323 }
1324 
1325 // -----------------------------------------------------------------------------
1326 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1327 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5)
1328 {
1329  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1330  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
1331 }
1332 
1333 // -----------------------------------------------------------------------------
1334 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1335 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
1336 {
1338  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1339  parallel_reduce(re, body);
1340  vf.join(body._VoxelFunc);
1341  of.join(body._OutsideFunc);
1342  } else {
1343  parallel_for(re, body);
1344  }
1345 }
1346 
1347 // -----------------------------------------------------------------------------
1348 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1349 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, const GenericImage<T5> *im5)
1350 {
1351  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1352  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
1353 }
1354 
1355 // -----------------------------------------------------------------------------
1356 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1357 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1358 {
1360  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
1361 }
1362 
1363 // -----------------------------------------------------------------------------
1364 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1365 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, const GenericImage<T5> *im5)
1366 {
1367  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1368  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
1369 }
1370 
1371 // -----------------------------------------------------------------------------
1372 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1373 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
1374 {
1376  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1377  parallel_reduce(re, body);
1378  vf.join(body._VoxelFunc);
1379  of.join(body._OutsideFunc);
1380  } else {
1381  parallel_for(re, body);
1382  }
1383 }
1384 
1385 // -----------------------------------------------------------------------------
1386 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1387 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, const GenericImage<T5> *im5)
1388 {
1389  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1390  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
1391 }
1392 
1393 // -----------------------------------------------------------------------------
1394 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1395 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1396 {
1398  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
1399 }
1400 
1401 // -----------------------------------------------------------------------------
1402 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1403 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, const GenericImage<T5> *im5)
1404 {
1405  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1406  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
1407 }
1408 
1409 // -----------------------------------------------------------------------------
1410 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1411 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
1412 {
1414  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1415  parallel_reduce(re, body);
1416  vf.join(body._VoxelFunc);
1417  of.join(body._OutsideFunc);
1418  } else {
1419  parallel_for(re, body);
1420  }
1421 }
1422 
1423 // -----------------------------------------------------------------------------
1424 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1425 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, const GenericImage<T5> *im5)
1426 {
1427  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1428  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
1429 }
1430 
1431 // -----------------------------------------------------------------------------
1432 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1433 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, const GenericImage<T5> *im5, VoxelFunc &vf)
1434 {
1436  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
1437 }
1438 
1439 // -----------------------------------------------------------------------------
1440 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1441 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, const GenericImage<T5> *im5)
1442 {
1443  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1444  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
1445 }
1446 
1447 //
1448 // Image arguments by reference
1449 //
1450 
1451 // -----------------------------------------------------------------------------
1452 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1453 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
1454 {
1457  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1458  parallel_reduce(re, body);
1459  vf.join(body._VoxelFunc);
1460  of.join(body._OutsideFunc);
1461  } else {
1462  parallel_for(re, body);
1463  }
1464 }
1465 
1466 // -----------------------------------------------------------------------------
1467 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1468 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1469 {
1470  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1471  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
1472 }
1473 
1474 // -----------------------------------------------------------------------------
1475 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1476 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1477 {
1479  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
1480 }
1481 
1482 // -----------------------------------------------------------------------------
1483 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1484 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1485 {
1486  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1487  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
1488 }
1489 
1490 // -----------------------------------------------------------------------------
1491 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1492 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
1493 {
1494  if (im5.GetTSize()) {
1495  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
1496  } else {
1498  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
1499  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1500  parallel_reduce(re, body);
1501  vf.join(body._VoxelFunc);
1502  of.join(body._OutsideFunc);
1503  } else {
1504  parallel_for(re, body);
1505  }
1506  }
1507 }
1508 
1509 // -----------------------------------------------------------------------------
1510 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1511 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1512 {
1513  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1514  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
1515 }
1516 
1517 // -----------------------------------------------------------------------------
1518 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1519 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1520 {
1522  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
1523 }
1524 
1525 // -----------------------------------------------------------------------------
1526 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1527 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1528 {
1529  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1530  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
1531 }
1532 
1533 // -----------------------------------------------------------------------------
1534 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1535 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
1536 {
1538  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1539  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1540  if (attr._dt) {
1541  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1542  } else {
1543  parallel_reduce(re, body);
1544  }
1545  vf.join(body._VoxelFunc);
1546  of.join(body._OutsideFunc);
1547  } else {
1548  if (attr._dt) {
1549  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1550  } else {
1551  parallel_for(re, body);
1552  }
1553  }
1554 }
1555 
1556 // -----------------------------------------------------------------------------
1557 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1558 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, const GenericImage<T5> &im5)
1559 {
1560  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1561  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
1562 }
1563 
1564 // -----------------------------------------------------------------------------
1565 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1566 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1567 {
1569  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
1570 }
1571 
1572 // -----------------------------------------------------------------------------
1573 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1574 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5)
1575 {
1576  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1577  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
1578 }
1579 
1580 // -----------------------------------------------------------------------------
1581 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1582 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
1583 {
1585  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1586  parallel_reduce(re, body);
1587  vf.join(body._VoxelFunc);
1588  of.join(body._OutsideFunc);
1589  } else {
1590  parallel_for(re, body);
1591  }
1592 }
1593 
1594 // -----------------------------------------------------------------------------
1595 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1596 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, const GenericImage<T5> &im5)
1597 {
1598  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1599  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
1600 }
1601 
1602 // -----------------------------------------------------------------------------
1603 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1604 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1605 {
1607  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
1608 }
1609 
1610 // -----------------------------------------------------------------------------
1611 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1612 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, const GenericImage<T5> &im5)
1613 {
1614  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1615  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
1616 }
1617 
1618 // -----------------------------------------------------------------------------
1619 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1620 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
1621 {
1623  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1624  parallel_reduce(re, body);
1625  vf.join(body._VoxelFunc);
1626  of.join(body._OutsideFunc);
1627  } else {
1628  parallel_for(re, body);
1629  }
1630 }
1631 
1632 // -----------------------------------------------------------------------------
1633 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1634 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, const GenericImage<T5> &im5)
1635 {
1636  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1637  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
1638 }
1639 
1640 // -----------------------------------------------------------------------------
1641 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1642 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1643 {
1645  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
1646 }
1647 
1648 // -----------------------------------------------------------------------------
1649 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1650 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, const GenericImage<T5> &im5)
1651 {
1652  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1653  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
1654 }
1655 
1656 // -----------------------------------------------------------------------------
1657 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1658 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
1659 {
1661  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1662  parallel_reduce(re, body);
1663  vf.join(body._VoxelFunc);
1664  of.join(body._OutsideFunc);
1665  } else {
1666  parallel_for(re, body);
1667  }
1668 }
1669 
1670 // -----------------------------------------------------------------------------
1671 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
1672 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, const GenericImage<T5> &im5)
1673 {
1674  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1675  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
1676 }
1677 
1678 // -----------------------------------------------------------------------------
1679 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1680 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, const GenericImage<T5> &im5, VoxelFunc &vf)
1681 {
1683  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
1684 }
1685 
1686 // -----------------------------------------------------------------------------
1687 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1688 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, const GenericImage<T5> &im5)
1689 {
1690  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1691  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
1692 }
1693 
1694 // =============================================================================
1695 // 4 const, 1 non-const images
1696 // =============================================================================
1697 
1698 // -----------------------------------------------------------------------------
1699 /**
1700  * ForEachVoxel body for voxel function of 4 const, 1 non-const images
1701  */
1702 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1704 {
1705  const GenericImage<T1> &im1;
1706  const GenericImage<T2> &im2;
1707  const GenericImage<T3> &im3;
1708  const GenericImage<T4> &im4;
1709  GenericImage<T5> &im5;
1710 
1711  /// Constructor
1713  const GenericImage<T2> &im2,
1714  const GenericImage<T3> &im3,
1715  const GenericImage<T4> &im4,
1716  GenericImage<T5> &im5,
1717  VoxelFunc &vf)
1718  :
1719  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
1720  {}
1721 
1722  /// Copy constructor
1724  :
1725  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
1726  {}
1727 
1728  /// Split constructor
1730  :
1731  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
1732  {}
1733 
1734  /// Process entire image
1735  void operator ()(const ImageAttributes &attr) const
1736  {
1737  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1738  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1739  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
1740  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
1741  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
1742 
1743  const int T = (attr._dt ? attr._t : 1);
1744 
1745  for (int l = 0; l < T; ++l)
1746  for (int k = 0; k < attr._z; ++k)
1747  for (int j = 0; j < attr._y; ++j)
1748  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
1749  // const_cast such that voxel functions need only implement
1750  // non-const operator() which is required for parallel_reduce
1751  const_cast<QuinaryForEachVoxelBody_4Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4, p5);
1752  }
1753  }
1754 
1755  /// Process image region using linear index
1756  void operator ()(const blocked_range<int> &re) const
1757  {
1758  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1759  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1760  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
1761  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
1762  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
1763 
1764  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
1765  // const_cast such that voxel functions need only implement
1766  // non-const operator() which is required for parallel_reduce
1767  const_cast<QuinaryForEachVoxelBody_4Const *>(this)->_VoxelFunc(im5, idx, p1, p2, p3, p4, p5);
1768  }
1769  }
1770 
1771  /// Process 2D image region
1772  void operator ()(const blocked_range2d<int> &re) const
1773  {
1774  const int bi = re.cols().begin();
1775  const int bj = re.rows().begin();
1776  const int ei = re.cols().end();
1777  const int ej = re.rows().end();
1778 
1779  const int s1 = im5.GetX() - (ei - bi);
1780 
1781  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1782  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1783  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1784  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1785  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1786 
1787  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
1788  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
1789  // const_cast such that voxel functions need only implement
1790  // non-const operator() which is required for parallel_reduce
1791  const_cast<QuinaryForEachVoxelBody_4Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
1792  }
1793  }
1794 
1795  /// Process 3D image region
1796  void operator ()(const blocked_range3d<int> &re) const
1797  {
1798  const int bi = re.cols ().begin();
1799  const int bj = re.rows ().begin();
1800  const int bk = re.pages().begin();
1801  const int ei = re.cols ().end();
1802  const int ej = re.rows ().end();
1803  const int ek = re.pages().end();
1804 
1805  const int s1 = im5.GetX() - (ei - bi);
1806  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
1807 
1808  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1809  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1810  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
1811  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
1812  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
1813 
1814  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
1815  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
1816  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
1817  // const_cast such that voxel functions need only implement
1818  // non-const operator() which is required for parallel_reduce
1819  const_cast<QuinaryForEachVoxelBody_4Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
1820  }
1821  }
1822 };
1823 
1824 // -----------------------------------------------------------------------------
1825 /**
1826  * ForEachVoxel body for inside and outside unary voxel function of 4 const, 1 non-const images
1827  */
1828 template <class T1, class T2, class T3, class T4, class T5,
1829  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
1830  class Domain = ForEachVoxelDomain::Foreground>
1831 struct QuinaryForEachVoxelIfBody_4Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
1832 {
1833  const GenericImage<T1> &im1;
1834  const GenericImage<T2> &im2;
1835  const GenericImage<T3> &im3;
1836  const GenericImage<T4> &im4;
1837  GenericImage<T5> &im5;
1838 
1839  /// Constructor
1841  const GenericImage<T2> &im2,
1842  const GenericImage<T3> &im3,
1843  const GenericImage<T4> &im4,
1844  GenericImage<T5> &im5,
1845  VoxelFunc &vf, OutsideFunc &of)
1846  :
1847  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
1848  {}
1849 
1850  /// Copy constructor
1852  :
1853  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
1854  {}
1855 
1856  /// Split constructor
1858  :
1859  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
1860  {}
1861 
1862  /// Process entire image
1863  void operator ()(const ImageAttributes &attr) const
1864  {
1865  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1866  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1867  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
1868  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
1869  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
1870 
1871  const int T = (attr._dt ? attr._t : 1);
1872 
1873  for (int l = 0; l < T; ++l)
1874  for (int k = 0; k < attr._z; ++k)
1875  for (int j = 0; j < attr._y; ++j)
1876  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
1877  if (Domain::IsInside(im5, i, j, k, l, p5)) {
1878  // const_cast such that voxel functions need only implement
1879  // non-const operator() which is required for parallel_reduce
1880  const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4, p5);
1881  } else const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4, p5);
1882  }
1883  }
1884 
1885  /// Process image region using linear index
1886  void operator ()(const blocked_range<int> &re) const
1887  {
1888  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1889  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1890  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
1891  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
1892  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
1893 
1894  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
1895  if (Domain::IsInside(im5, idx, p5)) {
1896  // const_cast such that voxel functions need only implement
1897  // non-const operator() which is required for parallel_reduce
1898  const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_VoxelFunc (im5, idx, p1, p2, p3, p4, p5);
1899  } else const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_OutsideFunc(im5, idx, p1, p2, p3, p4, p5);
1900  }
1901  }
1902 
1903  /// Process 2D image region
1904  void operator ()(const blocked_range2d<int> &re) const
1905  {
1906  const int bi = re.cols().begin();
1907  const int bj = re.rows().begin();
1908  const int ei = re.cols().end();
1909  const int ej = re.rows().end();
1910 
1911  const int s1 = im5.GetX() - (ei - bi);
1912 
1913  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1914  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1915  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1916  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1917  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1918 
1919  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
1920  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
1921  if (Domain::IsInside(im5, i, j, this->_k, this->_l, p5)) {
1922  // const_cast such that voxel functions need only implement
1923  // non-const operator() which is required for parallel_reduce
1924  const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
1925  } else const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
1926  }
1927  }
1928 
1929  /// Process 3D image region
1930  void operator ()(const blocked_range3d<int> &re) const
1931  {
1932  const int bi = re.cols ().begin();
1933  const int bj = re.rows ().begin();
1934  const int bk = re.pages().begin();
1935  const int ei = re.cols ().end();
1936  const int ej = re.rows ().end();
1937  const int ek = re.pages().end();
1938 
1939  const int s1 = im5.GetX() - (ei - bi);
1940  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
1941 
1942  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1943  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1944  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
1945  const T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
1946  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
1947 
1948  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
1949  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
1950  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
1951  if (Domain::IsInside(im5, i, j, k, this->_l, p5)) {
1952  // const_cast such that voxel functions need only implement
1953  // non-const operator() which is required for parallel_reduce
1954  const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4, p5);
1955  } else const_cast<QuinaryForEachVoxelIfBody_4Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
1956  }
1957  }
1958 };
1959 
1960 // -----------------------------------------------------------------------------
1961 // ForEachVoxel
1962 // -----------------------------------------------------------------------------
1963 
1964 //
1965 // Image arguments by pointer
1966 //
1967 
1968 // -----------------------------------------------------------------------------
1969 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1970 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
1971 {
1972  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
1973  blocked_range<int> re(0, im5->GetNumberOfVoxels());
1974  body(re);
1975  vf.join(body._VoxelFunc);
1976 }
1977 
1978 // -----------------------------------------------------------------------------
1979 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1980 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
1981 {
1982  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
1983  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
1984 }
1985 
1986 // -----------------------------------------------------------------------------
1987 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
1988 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
1989 {
1990  if (im5->GetTSize()) {
1991  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
1992  } else {
1993  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
1994  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
1995  body(re);
1996  vf.join(body._VoxelFunc);
1997  }
1998 }
1999 
2000 // -----------------------------------------------------------------------------
2001 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2002 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2003 {
2004  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2005  ForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
2006 }
2007 
2008 // -----------------------------------------------------------------------------
2009 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2010 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2011 {
2012  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2013  body(attr);
2014  vf.join(body._VoxelFunc);
2015 }
2016 
2017 // -----------------------------------------------------------------------------
2018 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2019 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2020 {
2021  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2022  ForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
2023 }
2024 
2025 // -----------------------------------------------------------------------------
2026 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2027 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2028 {
2029  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2030  body(re);
2031  vf.join(body._VoxelFunc);
2032 }
2033 
2034 // -----------------------------------------------------------------------------
2035 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2036 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, GenericImage<T5> *im5)
2037 {
2038  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2039  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
2040 }
2041 
2042 // -----------------------------------------------------------------------------
2043 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2044 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2045 {
2046  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2047  body(re);
2048  vf.join(body._VoxelFunc);
2049 }
2050 
2051 // -----------------------------------------------------------------------------
2052 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2053 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, GenericImage<T5> *im5)
2054 {
2055  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2056  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
2057 }
2058 
2059 // -----------------------------------------------------------------------------
2060 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2061 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2062 {
2063  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2064  body(re);
2065  vf.join(body._VoxelFunc);
2066 }
2067 
2068 // -----------------------------------------------------------------------------
2069 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2070 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, GenericImage<T5> *im5)
2071 {
2072  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2073  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
2074 }
2075 
2076 //
2077 // Image arguments by reference
2078 //
2079 
2080 // -----------------------------------------------------------------------------
2081 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2082 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2083 {
2084  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2086  body(re);
2087  vf.join(body._VoxelFunc);
2088 }
2089 
2090 // -----------------------------------------------------------------------------
2091 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2092 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2093 {
2094  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2095  ForEachScalar(im1, im2, im3, im4, im5, vf);
2096 }
2097 
2098 // -----------------------------------------------------------------------------
2099 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2100 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2101 {
2102  if (im5.GetTSize()) {
2103  ForEachScalar(im1, im2, im3, im4, im5, vf);
2104  } else {
2105  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2106  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
2107  body(re);
2108  vf.join(body._VoxelFunc);
2109  }
2110 }
2111 
2112 // -----------------------------------------------------------------------------
2113 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2114 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2115 {
2116  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2117  ForEachVoxel(im1, im2, im3, im4, im5, vf);
2118 }
2119 
2120 // -----------------------------------------------------------------------------
2121 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2122 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2123 {
2124  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2125  body(attr);
2126  vf.join(body._VoxelFunc);
2127 }
2128 
2129 // -----------------------------------------------------------------------------
2130 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2131 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2132 {
2133  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2134  ForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
2135 }
2136 
2137 // -----------------------------------------------------------------------------
2138 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2139 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2140 {
2141  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2142  body(re);
2143  vf.join(body._VoxelFunc);
2144 }
2145 
2146 // -----------------------------------------------------------------------------
2147 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2148 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, GenericImage<T5> &im5)
2149 {
2150  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2151  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
2152 }
2153 
2154 // -----------------------------------------------------------------------------
2155 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2156 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2157 {
2158  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2159  body(re);
2160  vf.join(body._VoxelFunc);
2161 }
2162 
2163 // -----------------------------------------------------------------------------
2164 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2165 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, GenericImage<T5> &im5)
2166 {
2167  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2168  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
2169 }
2170 
2171 // -----------------------------------------------------------------------------
2172 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2173 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2174 {
2175  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2176  body(re);
2177  vf.join(body._VoxelFunc);
2178 }
2179 
2180 // -----------------------------------------------------------------------------
2181 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2182 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, GenericImage<T5> &im5)
2183 {
2184  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2185  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
2186 }
2187 
2188 // -----------------------------------------------------------------------------
2189 // ForEachVoxelIf
2190 // -----------------------------------------------------------------------------
2191 
2192 //
2193 // Image arguments by pointer
2194 //
2195 
2196 // -----------------------------------------------------------------------------
2197 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2198 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2199 {
2201  blocked_range<int> re(0, im5->GetNumberOfVoxels());
2202  body(re);
2203  vf.join(body._VoxelFunc);
2204  of.join(body._OutsideFunc);
2205 }
2206 
2207 // -----------------------------------------------------------------------------
2208 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2209 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2210 {
2211  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2212  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2213 }
2214 
2215 // -----------------------------------------------------------------------------
2216 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2217 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2218 {
2220  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2221 }
2222 
2223 // -----------------------------------------------------------------------------
2224 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2225 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2226 {
2227  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2228  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
2229 }
2230 
2231 // -----------------------------------------------------------------------------
2232 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2233 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2234 {
2235  if (im5->GetTSize()) {
2236  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2237  } else {
2239  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
2240  body(re);
2241  vf.join(body._VoxelFunc);
2242  of.join(body._OutsideFunc);
2243  }
2244 }
2245 
2246 // -----------------------------------------------------------------------------
2247 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2248 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2249 {
2250  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2251  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2252 }
2253 
2254 // -----------------------------------------------------------------------------
2255 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2256 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2257 {
2259  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2260 }
2261 
2262 // -----------------------------------------------------------------------------
2263 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2264 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2265 {
2266  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2267  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
2268 }
2269 
2270 // -----------------------------------------------------------------------------
2271 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2272 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2273 {
2275  body(attr);
2276  vf.join(body._VoxelFunc);
2277  of.join(body._OutsideFunc);
2278 }
2279 
2280 // -----------------------------------------------------------------------------
2281 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2282 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, GenericImage<T5> *im5)
2283 {
2284  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2285  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
2286 }
2287 
2288 // -----------------------------------------------------------------------------
2289 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2290 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2291 {
2293  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
2294 }
2295 
2296 // -----------------------------------------------------------------------------
2297 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2298 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2299 {
2300  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2301  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
2302 }
2303 
2304 // -----------------------------------------------------------------------------
2305 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2306 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2307 {
2309  body(re);
2310  vf.join(body._VoxelFunc);
2311  of.join(body._OutsideFunc);
2312 }
2313 
2314 // -----------------------------------------------------------------------------
2315 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2316 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, GenericImage<T5> *im5)
2317 {
2318  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2319  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
2320 }
2321 
2322 // -----------------------------------------------------------------------------
2323 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2324 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2325 {
2327  body(re);
2328  vf.join(body._VoxelFunc);
2329  of.join(body._OutsideFunc);
2330 }
2331 
2332 // -----------------------------------------------------------------------------
2333 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2334 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, GenericImage<T5> *im5)
2335 {
2336  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2337  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
2338 }
2339 
2340 // -----------------------------------------------------------------------------
2341 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2342 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2343 {
2345  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
2346 }
2347 
2348 // -----------------------------------------------------------------------------
2349 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2350 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, GenericImage<T5> *im5)
2351 {
2352  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2353  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
2354 }
2355 
2356 // -----------------------------------------------------------------------------
2357 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2358 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2359 {
2361  body(re);
2362  vf.join(body._VoxelFunc);
2363  of.join(body._OutsideFunc);
2364 }
2365 
2366 // -----------------------------------------------------------------------------
2367 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2368 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, GenericImage<T5> *im5)
2369 {
2370  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2371  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2372 }
2373 
2374 // -----------------------------------------------------------------------------
2375 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2376 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2377 {
2379  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
2380 }
2381 
2382 // -----------------------------------------------------------------------------
2383 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2384 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, GenericImage<T5> *im5)
2385 {
2386  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2387  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
2388 }
2389 
2390 //
2391 // Image arguments by reference
2392 //
2393 
2394 // -----------------------------------------------------------------------------
2395 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2396 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
2397 {
2400  body(re);
2401  vf.join(body._VoxelFunc);
2402  of.join(body._OutsideFunc);
2403 }
2404 
2405 // -----------------------------------------------------------------------------
2406 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2407 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2408 {
2409  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2410  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
2411 }
2412 
2413 // -----------------------------------------------------------------------------
2414 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2415 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2416 {
2418  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
2419 }
2420 
2421 // -----------------------------------------------------------------------------
2422 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2423 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2424 {
2425  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2426  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
2427 }
2428 
2429 // -----------------------------------------------------------------------------
2430 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2431 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
2432 {
2433  if (im5.GetTSize()) {
2434  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
2435  } else {
2437  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
2438  body(re);
2439  vf.join(body._VoxelFunc);
2440  of.join(body._OutsideFunc);
2441  }
2442 }
2443 
2444 // -----------------------------------------------------------------------------
2445 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2446 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2447 {
2448  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2449  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
2450 }
2451 
2452 // -----------------------------------------------------------------------------
2453 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2454 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2455 {
2457  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
2458 }
2459 
2460 // -----------------------------------------------------------------------------
2461 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2462 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2463 {
2464  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2465  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
2466 }
2467 
2468 // -----------------------------------------------------------------------------
2469 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2470 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
2471 {
2473  body(attr);
2474  vf.join(body._VoxelFunc);
2475  of.join(body._OutsideFunc);
2476 }
2477 
2478 // -----------------------------------------------------------------------------
2479 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2480 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, GenericImage<T5> &im5)
2481 {
2482  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2483  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
2484 }
2485 
2486 // -----------------------------------------------------------------------------
2487 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2488 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2489 {
2491  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
2492 }
2493 
2494 // -----------------------------------------------------------------------------
2495 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2496 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2497 {
2498  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2499  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
2500 }
2501 
2502 // -----------------------------------------------------------------------------
2503 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2504 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
2505 {
2507  body(re);
2508  vf.join(body._VoxelFunc);
2509  of.join(body._OutsideFunc);
2510 }
2511 
2512 // -----------------------------------------------------------------------------
2513 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2514 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, GenericImage<T5> &im5)
2515 {
2516  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2517  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
2518 }
2519 
2520 // -----------------------------------------------------------------------------
2521 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2522 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
2523 {
2525  body(re);
2526  vf.join(body._VoxelFunc);
2527  of.join(body._OutsideFunc);
2528 }
2529 
2530 // -----------------------------------------------------------------------------
2531 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2532 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, GenericImage<T5> &im5)
2533 {
2534  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2535  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
2536 }
2537 
2538 // -----------------------------------------------------------------------------
2539 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2540 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2541 {
2543  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
2544 }
2545 
2546 // -----------------------------------------------------------------------------
2547 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2548 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, GenericImage<T5> &im5)
2549 {
2550  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2551  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
2552 }
2553 
2554 // -----------------------------------------------------------------------------
2555 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2556 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
2557 {
2559  body(re);
2560  vf.join(body._VoxelFunc);
2561  of.join(body._OutsideFunc);
2562 }
2563 
2564 // -----------------------------------------------------------------------------
2565 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2566 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, GenericImage<T5> &im5)
2567 {
2568  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2569  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
2570 }
2571 
2572 // -----------------------------------------------------------------------------
2573 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2574 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2575 {
2577  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
2578 }
2579 
2580 // -----------------------------------------------------------------------------
2581 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2582 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, GenericImage<T5> &im5)
2583 {
2584  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2585  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
2586 }
2587 
2588 // -----------------------------------------------------------------------------
2589 // ParallelForEachVoxel
2590 // -----------------------------------------------------------------------------
2591 
2592 //
2593 // Image arguments by pointer
2594 //
2595 
2596 // -----------------------------------------------------------------------------
2597 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2598 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2599 {
2600  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2601  blocked_range<int> re(0, im5->GetNumberOfVoxels());
2602  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2603  else parallel_for (re, body);
2604 }
2605 
2606 // -----------------------------------------------------------------------------
2607 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2608 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2609 {
2610  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2611  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
2612 }
2613 
2614 // -----------------------------------------------------------------------------
2615 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2616 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2617 {
2618  if (im5->GetTSize()) {
2619  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
2620  } else {
2621  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2622  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
2623  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2624  else parallel_for (re, body);
2625  }
2626 }
2627 
2628 // -----------------------------------------------------------------------------
2629 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2630 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2631 {
2632  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2633  ParallelForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
2634 }
2635 
2636 // -----------------------------------------------------------------------------
2637 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2638 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2639 {
2640  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2641  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2642  if (VoxelFunc::IsReduction()) {
2643  if (attr._dt) {
2644  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2645  } else {
2646  parallel_reduce(re, body);
2647  }
2648  vf.join(body._VoxelFunc);
2649  } else {
2650  if (attr._dt) {
2651  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2652  } else {
2653  parallel_for(re, body);
2654  }
2655  }
2656 }
2657 
2658 // -----------------------------------------------------------------------------
2659 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2660 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2661 {
2662  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2663  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
2664 }
2665 
2666 // -----------------------------------------------------------------------------
2667 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2668 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2669 {
2670  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2671  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2672  else parallel_for (re, body);
2673 }
2674 
2675 // -----------------------------------------------------------------------------
2676 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2677 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, GenericImage<T5> *im5)
2678 {
2679  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2680  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
2681 }
2682 
2683 // -----------------------------------------------------------------------------
2684 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2685 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2686 {
2687  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2688  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2689  else parallel_for (re, body);
2690 }
2691 
2692 // -----------------------------------------------------------------------------
2693 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2694 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, GenericImage<T5> *im5)
2695 {
2696  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2697  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
2698 }
2699 
2700 // -----------------------------------------------------------------------------
2701 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2702 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2703 {
2704  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
2705  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2706  else parallel_for (re, body);
2707 }
2708 
2709 // -----------------------------------------------------------------------------
2710 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2711 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, GenericImage<T5> *im5)
2712 {
2713  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2714  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
2715 }
2716 
2717 //
2718 // Image arguments by reference
2719 //
2720 
2721 // -----------------------------------------------------------------------------
2722 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2723 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2724 {
2725  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2727  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2728  else parallel_for (re, body);
2729 }
2730 
2731 // -----------------------------------------------------------------------------
2732 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2733 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2734 {
2735  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2736  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
2737 }
2738 
2739 // -----------------------------------------------------------------------------
2740 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2741 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2742 {
2743  if (im5.GetTSize()) {
2744  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
2745  } else {
2746  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2747  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
2748  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2749  else parallel_for (re, body);
2750  }
2751 }
2752 
2753 // -----------------------------------------------------------------------------
2754 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2755 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2756 {
2757  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2758  ParallelForEachVoxel(im1, im2, im3, im4, im5, vf);
2759 }
2760 
2761 // -----------------------------------------------------------------------------
2762 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2763 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2764 {
2765  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2766  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2767  if (VoxelFunc::IsReduction()) {
2768  if (attr._dt) {
2769  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2770  } else {
2771  parallel_reduce(re, body);
2772  }
2773  vf.join(body._VoxelFunc);
2774  } else {
2775  if (attr._dt) {
2776  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2777  } else {
2778  parallel_for(re, body);
2779  }
2780  }
2781 }
2782 
2783 // -----------------------------------------------------------------------------
2784 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2785 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
2786 {
2787  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2788  ParallelForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
2789 }
2790 
2791 // -----------------------------------------------------------------------------
2792 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2793 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2794 {
2795  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2796  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2797  else parallel_for (re, body);
2798 }
2799 
2800 // -----------------------------------------------------------------------------
2801 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2802 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, GenericImage<T5> &im5)
2803 {
2804  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2805  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
2806 }
2807 
2808 // -----------------------------------------------------------------------------
2809 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2810 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2811 {
2812  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2813  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2814  else parallel_for (re, body);
2815 }
2816 
2817 // -----------------------------------------------------------------------------
2818 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2819 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, GenericImage<T5> &im5)
2820 {
2821  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2822  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
2823 }
2824 
2825 // -----------------------------------------------------------------------------
2826 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2827 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
2828 {
2829  QuinaryForEachVoxelBody_4Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
2830  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2831  else parallel_for (re, body);
2832 }
2833 
2834 // -----------------------------------------------------------------------------
2835 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2836 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, GenericImage<T5> &im5)
2837 {
2838  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2839  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
2840 }
2841 
2842 // -----------------------------------------------------------------------------
2843 // ParallelForEachVoxelIf
2844 // -----------------------------------------------------------------------------
2845 
2846 //
2847 // Image arguments by pointer
2848 //
2849 
2850 // -----------------------------------------------------------------------------
2851 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2852 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2853 {
2855  blocked_range<int> re(0, im5->GetNumberOfVoxels());
2856  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2857  parallel_reduce(re, body);
2858  vf.join(body._VoxelFunc);
2859  of.join(body._OutsideFunc);
2860  } else {
2861  parallel_for(re, body);
2862  }
2863 }
2864 
2865 // -----------------------------------------------------------------------------
2866 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2867 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2868 {
2869  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2870  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2871 }
2872 
2873 // -----------------------------------------------------------------------------
2874 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2875 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2876 {
2878  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2879 }
2880 
2881 // -----------------------------------------------------------------------------
2882 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2883 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2884 {
2885  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2886  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
2887 }
2888 
2889 // -----------------------------------------------------------------------------
2890 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2891 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2892 {
2893  if (im5->GetTSize()) {
2894  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2895  } else {
2897  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
2898  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2899  parallel_reduce(re, body);
2900  vf.join(body._VoxelFunc);
2901  of.join(body._OutsideFunc);
2902  } else {
2903  parallel_for(re, body);
2904  }
2905  }
2906 }
2907 
2908 // -----------------------------------------------------------------------------
2909 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2910 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2911 {
2912  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2913  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2914 }
2915 
2916 // -----------------------------------------------------------------------------
2917 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2918 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2919 {
2921  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
2922 }
2923 
2924 // -----------------------------------------------------------------------------
2925 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2926 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2927 {
2928  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2929  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
2930 }
2931 
2932 // -----------------------------------------------------------------------------
2933 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2934 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2935 {
2937  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2938  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2939  if (attr._dt) {
2940  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2941  } else {
2942  parallel_reduce(re, body);
2943  }
2944  vf.join(body._VoxelFunc);
2945  of.join(body._OutsideFunc);
2946  } else {
2947  if (attr._dt) {
2948  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2949  } else {
2950  parallel_for(re, body);
2951  }
2952  }
2953 }
2954 
2955 // -----------------------------------------------------------------------------
2956 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2957 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, GenericImage<T5> *im5)
2958 {
2959  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2960  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
2961 }
2962 
2963 // -----------------------------------------------------------------------------
2964 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2965 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
2966 {
2968  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
2969 }
2970 
2971 // -----------------------------------------------------------------------------
2972 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
2973 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5)
2974 {
2975  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2976  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
2977 }
2978 
2979 // -----------------------------------------------------------------------------
2980 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2981 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
2982 {
2984  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2985  parallel_reduce(re, body);
2986  vf.join(body._VoxelFunc);
2987  of.join(body._OutsideFunc);
2988  } else {
2989  parallel_for(re, body);
2990  }
2991 }
2992 
2993 // -----------------------------------------------------------------------------
2994 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
2995 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, GenericImage<T5> *im5)
2996 {
2997  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
2998  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
2999 }
3000 
3001 // -----------------------------------------------------------------------------
3002 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3003 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3004 {
3006  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3007 }
3008 
3009 // -----------------------------------------------------------------------------
3010 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3011 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, GenericImage<T5> *im5)
3012 {
3013  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3014  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
3015 }
3016 
3017 // -----------------------------------------------------------------------------
3018 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3019 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3020 {
3022  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3023  parallel_reduce(re, body);
3024  vf.join(body._VoxelFunc);
3025  of.join(body._OutsideFunc);
3026  } else {
3027  parallel_for(re, body);
3028  }
3029 }
3030 
3031 // -----------------------------------------------------------------------------
3032 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3033 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, GenericImage<T5> *im5)
3034 {
3035  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3036  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3037 }
3038 
3039 // -----------------------------------------------------------------------------
3040 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3041 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3042 {
3044  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3045 }
3046 
3047 // -----------------------------------------------------------------------------
3048 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3049 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, GenericImage<T5> *im5)
3050 {
3051  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3052  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
3053 }
3054 
3055 // -----------------------------------------------------------------------------
3056 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3057 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3058 {
3060  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3061  parallel_reduce(re, body);
3062  vf.join(body._VoxelFunc);
3063  of.join(body._OutsideFunc);
3064  } else {
3065  parallel_for(re, body);
3066  }
3067 }
3068 
3069 // -----------------------------------------------------------------------------
3070 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3071 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, GenericImage<T5> *im5)
3072 {
3073  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3074  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3075 }
3076 
3077 // -----------------------------------------------------------------------------
3078 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3079 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, const GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3080 {
3082  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3083 }
3084 
3085 // -----------------------------------------------------------------------------
3086 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3087 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, GenericImage<T5> *im5)
3088 {
3089  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3090  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
3091 }
3092 
3093 //
3094 // Image arguments by reference
3095 //
3096 
3097 // -----------------------------------------------------------------------------
3098 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3099 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
3100 {
3103  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3104  parallel_reduce(re, body);
3105  vf.join(body._VoxelFunc);
3106  of.join(body._OutsideFunc);
3107  } else {
3108  parallel_for(re, body);
3109  }
3110 }
3111 
3112 // -----------------------------------------------------------------------------
3113 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3114 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
3115 {
3116  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3117  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
3118 }
3119 
3120 // -----------------------------------------------------------------------------
3121 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3122 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3123 {
3125  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
3126 }
3127 
3128 // -----------------------------------------------------------------------------
3129 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3130 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
3131 {
3132  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3133  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
3134 }
3135 
3136 // -----------------------------------------------------------------------------
3137 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3138 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
3139 {
3140  if (im5.GetTSize()) {
3141  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
3142  } else {
3144  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
3145  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3146  parallel_reduce(re, body);
3147  vf.join(body._VoxelFunc);
3148  of.join(body._OutsideFunc);
3149  } else {
3150  parallel_for(re, body);
3151  }
3152  }
3153 }
3154 
3155 // -----------------------------------------------------------------------------
3156 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3157 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
3158 {
3159  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3160  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
3161 }
3162 
3163 // -----------------------------------------------------------------------------
3164 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3165 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3166 {
3168  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
3169 }
3170 
3171 // -----------------------------------------------------------------------------
3172 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3173 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
3174 {
3175  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3176  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
3177 }
3178 
3179 // -----------------------------------------------------------------------------
3180 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3181 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
3182 {
3184  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
3185  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3186  if (attr._dt) {
3187  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
3188  } else {
3189  parallel_reduce(re, body);
3190  }
3191  vf.join(body._VoxelFunc);
3192  of.join(body._OutsideFunc);
3193  } else {
3194  if (attr._dt) {
3195  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
3196  } else {
3197  parallel_for(re, body);
3198  }
3199  }
3200 }
3201 
3202 // -----------------------------------------------------------------------------
3203 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3204 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, GenericImage<T5> &im5)
3205 {
3206  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3207  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
3208 }
3209 
3210 // -----------------------------------------------------------------------------
3211 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3212 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3213 {
3215  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
3216 }
3217 
3218 // -----------------------------------------------------------------------------
3219 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3220 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5)
3221 {
3222  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3223  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
3224 }
3225 
3226 // -----------------------------------------------------------------------------
3227 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3228 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
3229 {
3231  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3232  parallel_reduce(re, body);
3233  vf.join(body._VoxelFunc);
3234  of.join(body._OutsideFunc);
3235  } else {
3236  parallel_for(re, body);
3237  }
3238 }
3239 
3240 // -----------------------------------------------------------------------------
3241 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3242 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, GenericImage<T5> &im5)
3243 {
3244  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3245  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
3246 }
3247 
3248 // -----------------------------------------------------------------------------
3249 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3250 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3251 {
3253  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
3254 }
3255 
3256 // -----------------------------------------------------------------------------
3257 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3258 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, GenericImage<T5> &im5)
3259 {
3260  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3261  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
3262 }
3263 
3264 // -----------------------------------------------------------------------------
3265 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3266 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
3267 {
3269  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3270  parallel_reduce(re, body);
3271  vf.join(body._VoxelFunc);
3272  of.join(body._OutsideFunc);
3273  } else {
3274  parallel_for(re, body);
3275  }
3276 }
3277 
3278 // -----------------------------------------------------------------------------
3279 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3280 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, GenericImage<T5> &im5)
3281 {
3282  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3283  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
3284 }
3285 
3286 // -----------------------------------------------------------------------------
3287 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3288 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3289 {
3291  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
3292 }
3293 
3294 // -----------------------------------------------------------------------------
3295 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3296 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, GenericImage<T5> &im5)
3297 {
3298  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3299  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
3300 }
3301 
3302 // -----------------------------------------------------------------------------
3303 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3304 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
3305 {
3307  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3308  parallel_reduce(re, body);
3309  vf.join(body._VoxelFunc);
3310  of.join(body._OutsideFunc);
3311  } else {
3312  parallel_for(re, body);
3313  }
3314 }
3315 
3316 // -----------------------------------------------------------------------------
3317 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3318 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, GenericImage<T5> &im5)
3319 {
3320  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3321  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
3322 }
3323 
3324 // -----------------------------------------------------------------------------
3325 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3326 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, const GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3327 {
3329  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
3330 }
3331 
3332 // -----------------------------------------------------------------------------
3333 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3334 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, GenericImage<T5> &im5)
3335 {
3336  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3337  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
3338 }
3339 
3340 // =============================================================================
3341 // 3 const, 2 non-const images
3342 // =============================================================================
3343 
3344 // -----------------------------------------------------------------------------
3345 /**
3346  * ForEachVoxel body for voxel function of 3 const, 2 non-const images
3347  */
3348 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3350 {
3351  const GenericImage<T1> &im1;
3352  const GenericImage<T2> &im2;
3353  const GenericImage<T3> &im3;
3354  GenericImage<T4> &im4;
3355  GenericImage<T5> &im5;
3356 
3357  /// Constructor
3359  const GenericImage<T2> &im2,
3360  const GenericImage<T3> &im3,
3361  GenericImage<T4> &im4,
3362  GenericImage<T5> &im5,
3363  VoxelFunc &vf)
3364  :
3365  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
3366  {}
3367 
3368  /// Copy constructor
3370  :
3371  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
3372  {}
3373 
3374  /// Split constructor
3376  :
3377  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
3378  {}
3379 
3380  /// Process entire image
3381  void operator ()(const ImageAttributes &attr) const
3382  {
3383  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3384  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3385  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
3386  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
3387  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
3388 
3389  const int T = (attr._dt ? attr._t : 1);
3390 
3391  for (int l = 0; l < T; ++l)
3392  for (int k = 0; k < attr._z; ++k)
3393  for (int j = 0; j < attr._y; ++j)
3394  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
3395  // const_cast such that voxel functions need only implement
3396  // non-const operator() which is required for parallel_reduce
3397  const_cast<QuinaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4, p5);
3398  }
3399  }
3400 
3401  /// Process image region using linear index
3402  void operator ()(const blocked_range<int> &re) const
3403  {
3404  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3405  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3406  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
3407  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
3408  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
3409 
3410  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
3411  // const_cast such that voxel functions need only implement
3412  // non-const operator() which is required for parallel_reduce
3413  const_cast<QuinaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(im5, idx, p1, p2, p3, p4, p5);
3414  }
3415  }
3416 
3417  /// Process 2D image region
3418  void operator ()(const blocked_range2d<int> &re) const
3419  {
3420  const int bi = re.cols().begin();
3421  const int bj = re.rows().begin();
3422  const int ei = re.cols().end();
3423  const int ej = re.rows().end();
3424 
3425  const int s1 = im5.GetX() - (ei - bi);
3426 
3427  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3428  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3429  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3430  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3431  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3432 
3433  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
3434  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
3435  // const_cast such that voxel functions need only implement
3436  // non-const operator() which is required for parallel_reduce
3437  const_cast<QuinaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
3438  }
3439  }
3440 
3441  /// Process 3D image region
3442  void operator ()(const blocked_range3d<int> &re) const
3443  {
3444  const int bi = re.cols ().begin();
3445  const int bj = re.rows ().begin();
3446  const int bk = re.pages().begin();
3447  const int ei = re.cols ().end();
3448  const int ej = re.rows ().end();
3449  const int ek = re.pages().end();
3450 
3451  const int s1 = im5.GetX() - (ei - bi);
3452  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
3453 
3454  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3455  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3456  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
3457  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
3458  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
3459 
3460  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
3461  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
3462  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
3463  // const_cast such that voxel functions need only implement
3464  // non-const operator() which is required for parallel_reduce
3465  const_cast<QuinaryForEachVoxelBody_3Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
3466  }
3467  }
3468 };
3469 
3470 // -----------------------------------------------------------------------------
3471 /**
3472  * ForEachVoxel body for inside and outside unary voxel function of 3 const, 2 non-const images
3473  */
3474 template <class T1, class T2, class T3, class T4, class T5,
3475  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
3476  class Domain = ForEachVoxelDomain::Foreground>
3477 struct QuinaryForEachVoxelIfBody_3Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
3478 {
3479  const GenericImage<T1> &im1;
3480  const GenericImage<T2> &im2;
3481  const GenericImage<T3> &im3;
3482  GenericImage<T4> &im4;
3483  GenericImage<T5> &im5;
3484 
3485  /// Constructor
3487  const GenericImage<T2> &im2,
3488  const GenericImage<T3> &im3,
3489  GenericImage<T4> &im4,
3490  GenericImage<T5> &im5,
3491  VoxelFunc &vf, OutsideFunc &of)
3492  :
3493  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
3494  {}
3495 
3496  /// Copy constructor
3498  :
3499  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
3500  {}
3501 
3502  /// Split constructor
3504  :
3505  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
3506  {}
3507 
3508  /// Process entire image
3509  void operator ()(const ImageAttributes &attr) const
3510  {
3511  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3512  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3513  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
3514  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
3515  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
3516 
3517  const int T = (attr._dt ? attr._t : 1);
3518 
3519  for (int l = 0; l < T; ++l)
3520  for (int k = 0; k < attr._z; ++k)
3521  for (int j = 0; j < attr._y; ++j)
3522  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
3523  if (Domain::IsInside(im5, i, j, k, l, p5)) {
3524  // const_cast such that voxel functions need only implement
3525  // non-const operator() which is required for parallel_reduce
3526  const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4, p5);
3527  } else const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4, p5);
3528  }
3529  }
3530 
3531  /// Process image region using linear index
3532  void operator ()(const blocked_range<int> &re) const
3533  {
3534  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3535  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3536  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
3537  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
3538  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
3539 
3540  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
3541  if (Domain::IsInside(im5, idx, p5)) {
3542  // const_cast such that voxel functions need only implement
3543  // non-const operator() which is required for parallel_reduce
3544  const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (im5, idx, p1, p2, p3, p4, p5);
3545  } else const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(im5, idx, p1, p2, p3, p4, p5);
3546  }
3547  }
3548 
3549  /// Process 2D image region
3550  void operator ()(const blocked_range2d<int> &re) const
3551  {
3552  const int bi = re.cols().begin();
3553  const int bj = re.rows().begin();
3554  const int ei = re.cols().end();
3555  const int ej = re.rows().end();
3556 
3557  const int s1 = im5.GetX() - (ei - bi);
3558 
3559  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3560  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3561  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3562  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3563  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3564 
3565  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
3566  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
3567  if (Domain::IsInside(im5, i, j, this->_k, this->_l, p5)) {
3568  // const_cast such that voxel functions need only implement
3569  // non-const operator() which is required for parallel_reduce
3570  const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
3571  } else const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
3572  }
3573  }
3574 
3575  /// Process 3D image region
3576  void operator ()(const blocked_range3d<int> &re) const
3577  {
3578  const int bi = re.cols ().begin();
3579  const int bj = re.rows ().begin();
3580  const int bk = re.pages().begin();
3581  const int ei = re.cols ().end();
3582  const int ej = re.rows ().end();
3583  const int ek = re.pages().end();
3584 
3585  const int s1 = im5.GetX() - (ei - bi);
3586  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
3587 
3588  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3589  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3590  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
3591  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
3592  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
3593 
3594  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
3595  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
3596  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
3597  if (Domain::IsInside(im5, i, j, k, this->_l, p5)) {
3598  // const_cast such that voxel functions need only implement
3599  // non-const operator() which is required for parallel_reduce
3600  const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4, p5);
3601  } else const_cast<QuinaryForEachVoxelIfBody_3Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
3602  }
3603  }
3604 };
3605 
3606 // -----------------------------------------------------------------------------
3607 // ForEachVoxel
3608 // -----------------------------------------------------------------------------
3609 
3610 //
3611 // Image arguments by pointer
3612 //
3613 
3614 // -----------------------------------------------------------------------------
3615 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3616 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3617 {
3618  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
3619  blocked_range<int> re(0, im5->GetNumberOfVoxels());
3620  body(re);
3621  vf.join(body._VoxelFunc);
3622 }
3623 
3624 // -----------------------------------------------------------------------------
3625 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3626 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3627 {
3628  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3629  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
3630 }
3631 
3632 // -----------------------------------------------------------------------------
3633 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3634 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3635 {
3636  if (im5->GetTSize()) {
3637  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
3638  } else {
3639  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
3640  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
3641  body(re);
3642  vf.join(body._VoxelFunc);
3643  }
3644 }
3645 
3646 // -----------------------------------------------------------------------------
3647 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3648 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3649 {
3650  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3651  ForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
3652 }
3653 
3654 // -----------------------------------------------------------------------------
3655 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3656 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3657 {
3658  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
3659  body(attr);
3660  vf.join(body._VoxelFunc);
3661 }
3662 
3663 // -----------------------------------------------------------------------------
3664 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3665 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3666 {
3667  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3668  ForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
3669 }
3670 
3671 // -----------------------------------------------------------------------------
3672 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3673 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3674 {
3675  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
3676  body(re);
3677  vf.join(body._VoxelFunc);
3678 }
3679 
3680 // -----------------------------------------------------------------------------
3681 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3682 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3683 {
3684  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3685  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
3686 }
3687 
3688 // -----------------------------------------------------------------------------
3689 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3690 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3691 {
3692  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
3693  body(re);
3694  vf.join(body._VoxelFunc);
3695 }
3696 
3697 // -----------------------------------------------------------------------------
3698 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3699 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3700 {
3701  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3702  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
3703 }
3704 
3705 // -----------------------------------------------------------------------------
3706 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3707 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3708 {
3709  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
3710  body(re);
3711  vf.join(body._VoxelFunc);
3712 }
3713 
3714 // -----------------------------------------------------------------------------
3715 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3716 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3717 {
3718  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3719  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
3720 }
3721 
3722 //
3723 // Image arguments by reference
3724 //
3725 
3726 // -----------------------------------------------------------------------------
3727 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3728 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3729 {
3730  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
3732  body(re);
3733  vf.join(body._VoxelFunc);
3734 }
3735 
3736 // -----------------------------------------------------------------------------
3737 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3738 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
3739 {
3740  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3741  ForEachScalar(im1, im2, im3, im4, im5, vf);
3742 }
3743 
3744 // -----------------------------------------------------------------------------
3745 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3746 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3747 {
3748  if (im5.GetTSize()) {
3749  ForEachScalar(im1, im2, im3, im4, im5, vf);
3750  } else {
3751  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
3752  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
3753  body(re);
3754  vf.join(body._VoxelFunc);
3755  }
3756 }
3757 
3758 // -----------------------------------------------------------------------------
3759 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3760 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
3761 {
3762  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3763  ForEachVoxel(im1, im2, im3, im4, im5, vf);
3764 }
3765 
3766 // -----------------------------------------------------------------------------
3767 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3768 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3769 {
3770  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
3771  body(attr);
3772  vf.join(body._VoxelFunc);
3773 }
3774 
3775 // -----------------------------------------------------------------------------
3776 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3777 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
3778 {
3779  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3780  ForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
3781 }
3782 
3783 // -----------------------------------------------------------------------------
3784 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3785 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3786 {
3787  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
3788  body(re);
3789  vf.join(body._VoxelFunc);
3790 }
3791 
3792 // -----------------------------------------------------------------------------
3793 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3794 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
3795 {
3796  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3797  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
3798 }
3799 
3800 // -----------------------------------------------------------------------------
3801 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3802 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3803 {
3804  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
3805  body(re);
3806  vf.join(body._VoxelFunc);
3807 }
3808 
3809 // -----------------------------------------------------------------------------
3810 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3811 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
3812 {
3813  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3814  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
3815 }
3816 
3817 // -----------------------------------------------------------------------------
3818 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3819 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
3820 {
3821  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
3822  body(re);
3823  vf.join(body._VoxelFunc);
3824 }
3825 
3826 // -----------------------------------------------------------------------------
3827 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3828 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
3829 {
3830  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3831  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
3832 }
3833 
3834 // -----------------------------------------------------------------------------
3835 // ForEachVoxelIf
3836 // -----------------------------------------------------------------------------
3837 
3838 //
3839 // Image arguments by pointer
3840 //
3841 
3842 // -----------------------------------------------------------------------------
3843 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3844 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3845 {
3847  blocked_range<int> re(0, im5->GetNumberOfVoxels());
3848  body(re);
3849  vf.join(body._VoxelFunc);
3850  of.join(body._OutsideFunc);
3851 }
3852 
3853 // -----------------------------------------------------------------------------
3854 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3855 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3856 {
3857  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3858  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
3859 }
3860 
3861 // -----------------------------------------------------------------------------
3862 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3863 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3864 {
3866  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
3867 }
3868 
3869 // -----------------------------------------------------------------------------
3870 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3871 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3872 {
3873  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3874  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
3875 }
3876 
3877 // -----------------------------------------------------------------------------
3878 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3879 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3880 {
3881  if (im5->GetTSize()) {
3882  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
3883  } else {
3885  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
3886  body(re);
3887  vf.join(body._VoxelFunc);
3888  of.join(body._OutsideFunc);
3889  }
3890 }
3891 
3892 // -----------------------------------------------------------------------------
3893 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3894 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3895 {
3896  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3897  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
3898 }
3899 
3900 // -----------------------------------------------------------------------------
3901 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3902 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3903 {
3905  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
3906 }
3907 
3908 // -----------------------------------------------------------------------------
3909 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3910 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3911 {
3912  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3913  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
3914 }
3915 
3916 // -----------------------------------------------------------------------------
3917 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3918 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3919 {
3921  body(attr);
3922  vf.join(body._VoxelFunc);
3923  of.join(body._OutsideFunc);
3924 }
3925 
3926 // -----------------------------------------------------------------------------
3927 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3928 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3929 {
3930  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3931  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
3932 }
3933 
3934 // -----------------------------------------------------------------------------
3935 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3936 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3937 {
3939  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
3940 }
3941 
3942 // -----------------------------------------------------------------------------
3943 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3944 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3945 {
3946  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3947  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
3948 }
3949 
3950 // -----------------------------------------------------------------------------
3951 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3952 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3953 {
3955  body(re);
3956  vf.join(body._VoxelFunc);
3957  of.join(body._OutsideFunc);
3958 }
3959 
3960 // -----------------------------------------------------------------------------
3961 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3962 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, GenericImage<T5> *im5)
3963 {
3964  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3965  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3966 }
3967 
3968 // -----------------------------------------------------------------------------
3969 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3970 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
3971 {
3973  body(re);
3974  vf.join(body._VoxelFunc);
3975  of.join(body._OutsideFunc);
3976 }
3977 
3978 // -----------------------------------------------------------------------------
3979 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
3980 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, GenericImage<T5> *im5)
3981 {
3982  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3983  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3984 }
3985 
3986 // -----------------------------------------------------------------------------
3987 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3988 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
3989 {
3991  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
3992 }
3993 
3994 // -----------------------------------------------------------------------------
3995 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
3996 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
3997 {
3998  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
3999  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
4000 }
4001 
4002 // -----------------------------------------------------------------------------
4003 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4004 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4005 {
4007  body(re);
4008  vf.join(body._VoxelFunc);
4009  of.join(body._OutsideFunc);
4010 }
4011 
4012 // -----------------------------------------------------------------------------
4013 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4014 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, GenericImage<T5> *im5)
4015 {
4016  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4017  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
4018 }
4019 
4020 // -----------------------------------------------------------------------------
4021 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4022 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4023 {
4025  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4026 }
4027 
4028 // -----------------------------------------------------------------------------
4029 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4030 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4031 {
4032  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4033  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
4034 }
4035 
4036 //
4037 // Image arguments by reference
4038 //
4039 
4040 // -----------------------------------------------------------------------------
4041 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4042 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4043 {
4046  body(re);
4047  vf.join(body._VoxelFunc);
4048  of.join(body._OutsideFunc);
4049 }
4050 
4051 // -----------------------------------------------------------------------------
4052 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4053 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4054 {
4055  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4056  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4057 }
4058 
4059 // -----------------------------------------------------------------------------
4060 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4061 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4062 {
4064  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4065 }
4066 
4067 // -----------------------------------------------------------------------------
4068 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4069 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4070 {
4071  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4072  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
4073 }
4074 
4075 // -----------------------------------------------------------------------------
4076 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4077 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4078 {
4079  if (im5.GetTSize()) {
4080  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4081  } else {
4083  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
4084  body(re);
4085  vf.join(body._VoxelFunc);
4086  of.join(body._OutsideFunc);
4087  }
4088 }
4089 
4090 // -----------------------------------------------------------------------------
4091 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4092 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4093 {
4094  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4095  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4096 }
4097 
4098 // -----------------------------------------------------------------------------
4099 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4100 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4101 {
4103  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4104 }
4105 
4106 // -----------------------------------------------------------------------------
4107 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4108 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4109 {
4110  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4111  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
4112 }
4113 
4114 // -----------------------------------------------------------------------------
4115 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4116 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4117 {
4119  body(attr);
4120  vf.join(body._VoxelFunc);
4121  of.join(body._OutsideFunc);
4122 }
4123 
4124 // -----------------------------------------------------------------------------
4125 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4126 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4127 {
4128  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4129  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
4130 }
4131 
4132 // -----------------------------------------------------------------------------
4133 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4134 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4135 {
4137  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
4138 }
4139 
4140 // -----------------------------------------------------------------------------
4141 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4142 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4143 {
4144  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4145  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
4146 }
4147 
4148 // -----------------------------------------------------------------------------
4149 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4150 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4151 {
4153  body(re);
4154  vf.join(body._VoxelFunc);
4155  of.join(body._OutsideFunc);
4156 }
4157 
4158 // -----------------------------------------------------------------------------
4159 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4160 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, GenericImage<T5> &im5)
4161 {
4162  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4163  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4164 }
4165 
4166 // -----------------------------------------------------------------------------
4167 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4168 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4169 {
4171  body(re);
4172  vf.join(body._VoxelFunc);
4173  of.join(body._OutsideFunc);
4174 }
4175 
4176 // -----------------------------------------------------------------------------
4177 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4178 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, GenericImage<T5> &im5)
4179 {
4180  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4181  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4182 }
4183 
4184 // -----------------------------------------------------------------------------
4185 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4186 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4187 {
4189  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4190 }
4191 
4192 // -----------------------------------------------------------------------------
4193 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4194 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4195 {
4196  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4197  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
4198 }
4199 
4200 // -----------------------------------------------------------------------------
4201 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4202 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4203 {
4205  body(re);
4206  vf.join(body._VoxelFunc);
4207  of.join(body._OutsideFunc);
4208 }
4209 
4210 // -----------------------------------------------------------------------------
4211 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4212 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, GenericImage<T5> &im5)
4213 {
4214  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4215  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4216 }
4217 
4218 // -----------------------------------------------------------------------------
4219 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4220 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4221 {
4223  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4224 }
4225 
4226 // -----------------------------------------------------------------------------
4227 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4228 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4229 {
4230  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4231  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
4232 }
4233 
4234 // -----------------------------------------------------------------------------
4235 // ParallelForEachVoxel
4236 // -----------------------------------------------------------------------------
4237 
4238 //
4239 // Image arguments by pointer
4240 //
4241 
4242 // -----------------------------------------------------------------------------
4243 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4244 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4245 {
4246  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
4247  blocked_range<int> re(0, im5->GetNumberOfVoxels());
4248  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4249  else parallel_for (re, body);
4250 }
4251 
4252 // -----------------------------------------------------------------------------
4253 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4254 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4255 {
4256  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4257  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
4258 }
4259 
4260 // -----------------------------------------------------------------------------
4261 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4262 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4263 {
4264  if (im5->GetTSize()) {
4265  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
4266  } else {
4267  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
4268  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
4269  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4270  else parallel_for (re, body);
4271  }
4272 }
4273 
4274 // -----------------------------------------------------------------------------
4275 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4276 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4277 {
4278  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4279  ParallelForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
4280 }
4281 
4282 // -----------------------------------------------------------------------------
4283 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4284 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4285 {
4286  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
4287  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4288  if (VoxelFunc::IsReduction()) {
4289  if (attr._dt) {
4290  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4291  } else {
4292  parallel_reduce(re, body);
4293  }
4294  vf.join(body._VoxelFunc);
4295  } else {
4296  if (attr._dt) {
4297  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4298  } else {
4299  parallel_for(re, body);
4300  }
4301  }
4302 }
4303 
4304 // -----------------------------------------------------------------------------
4305 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4306 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4307 {
4308  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4309  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
4310 }
4311 
4312 // -----------------------------------------------------------------------------
4313 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4314 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4315 {
4316  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
4317  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4318  else parallel_for (re, body);
4319 }
4320 
4321 // -----------------------------------------------------------------------------
4322 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4323 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4324 {
4325  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4326  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
4327 }
4328 
4329 // -----------------------------------------------------------------------------
4330 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4331 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4332 {
4333  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
4334  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4335  else parallel_for (re, body);
4336 }
4337 
4338 // -----------------------------------------------------------------------------
4339 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4340 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4341 {
4342  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4343  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
4344 }
4345 
4346 // -----------------------------------------------------------------------------
4347 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4348 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4349 {
4350  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
4351  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4352  else parallel_for (re, body);
4353 }
4354 
4355 // -----------------------------------------------------------------------------
4356 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4357 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4358 {
4359  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4360  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
4361 }
4362 
4363 //
4364 // Image arguments by reference
4365 //
4366 
4367 // -----------------------------------------------------------------------------
4368 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4369 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4370 {
4371  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
4373  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4374  else parallel_for (re, body);
4375 }
4376 
4377 // -----------------------------------------------------------------------------
4378 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4379 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4380 {
4381  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4382  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
4383 }
4384 
4385 // -----------------------------------------------------------------------------
4386 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4387 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4388 {
4389  if (im5.GetTSize()) {
4390  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
4391  } else {
4392  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
4393  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
4394  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4395  else parallel_for (re, body);
4396  }
4397 }
4398 
4399 // -----------------------------------------------------------------------------
4400 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4401 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4402 {
4403  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4404  ParallelForEachVoxel(im1, im2, im3, im4, im5, vf);
4405 }
4406 
4407 // -----------------------------------------------------------------------------
4408 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4409 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4410 {
4411  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
4412  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4413  if (VoxelFunc::IsReduction()) {
4414  if (attr._dt) {
4415  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4416  } else {
4417  parallel_reduce(re, body);
4418  }
4419  vf.join(body._VoxelFunc);
4420  } else {
4421  if (attr._dt) {
4422  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4423  } else {
4424  parallel_for(re, body);
4425  }
4426  }
4427 }
4428 
4429 // -----------------------------------------------------------------------------
4430 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4431 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4432 {
4433  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4434  ParallelForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
4435 }
4436 
4437 // -----------------------------------------------------------------------------
4438 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4439 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4440 {
4441  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
4442  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4443  else parallel_for (re, body);
4444 }
4445 
4446 // -----------------------------------------------------------------------------
4447 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4448 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4449 {
4450  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4451  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
4452 }
4453 
4454 // -----------------------------------------------------------------------------
4455 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4456 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4457 {
4458  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
4459  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4460  else parallel_for (re, body);
4461 }
4462 
4463 // -----------------------------------------------------------------------------
4464 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4465 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4466 {
4467  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4468  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
4469 }
4470 
4471 // -----------------------------------------------------------------------------
4472 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4473 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4474 {
4475  QuinaryForEachVoxelBody_3Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
4476  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4477  else parallel_for (re, body);
4478 }
4479 
4480 // -----------------------------------------------------------------------------
4481 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4482 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4483 {
4484  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4485  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
4486 }
4487 
4488 // -----------------------------------------------------------------------------
4489 // ParallelForEachVoxelIf
4490 // -----------------------------------------------------------------------------
4491 
4492 //
4493 // Image arguments by pointer
4494 //
4495 
4496 // -----------------------------------------------------------------------------
4497 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4498 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4499 {
4501  blocked_range<int> re(0, im5->GetNumberOfVoxels());
4502  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4503  parallel_reduce(re, body);
4504  vf.join(body._VoxelFunc);
4505  of.join(body._OutsideFunc);
4506  } else {
4507  parallel_for(re, body);
4508  }
4509 }
4510 
4511 // -----------------------------------------------------------------------------
4512 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4513 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4514 {
4515  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4516  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
4517 }
4518 
4519 // -----------------------------------------------------------------------------
4520 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4521 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4522 {
4524  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
4525 }
4526 
4527 // -----------------------------------------------------------------------------
4528 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4529 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4530 {
4531  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4532  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
4533 }
4534 
4535 // -----------------------------------------------------------------------------
4536 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4537 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4538 {
4539  if (im5->GetTSize()) {
4540  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
4541  } else {
4543  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
4544  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4545  parallel_reduce(re, body);
4546  vf.join(body._VoxelFunc);
4547  of.join(body._OutsideFunc);
4548  } else {
4549  parallel_for(re, body);
4550  }
4551  }
4552 }
4553 
4554 // -----------------------------------------------------------------------------
4555 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4556 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4557 {
4558  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4559  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
4560 }
4561 
4562 // -----------------------------------------------------------------------------
4563 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4564 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4565 {
4567  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
4568 }
4569 
4570 // -----------------------------------------------------------------------------
4571 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4572 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4573 {
4574  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4575  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
4576 }
4577 
4578 // -----------------------------------------------------------------------------
4579 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4580 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4581 {
4583  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4584  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4585  if (attr._dt) {
4586  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4587  } else {
4588  parallel_reduce(re, body);
4589  }
4590  vf.join(body._VoxelFunc);
4591  of.join(body._OutsideFunc);
4592  } else {
4593  if (attr._dt) {
4594  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4595  } else {
4596  parallel_for(re, body);
4597  }
4598  }
4599 }
4600 
4601 // -----------------------------------------------------------------------------
4602 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4603 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4604 {
4605  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4606  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
4607 }
4608 
4609 // -----------------------------------------------------------------------------
4610 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4611 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4612 {
4614  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
4615 }
4616 
4617 // -----------------------------------------------------------------------------
4618 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4619 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4620 {
4621  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4622  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
4623 }
4624 
4625 // -----------------------------------------------------------------------------
4626 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4627 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4628 {
4630  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4631  parallel_reduce(re, body);
4632  vf.join(body._VoxelFunc);
4633  of.join(body._OutsideFunc);
4634  } else {
4635  parallel_for(re, body);
4636  }
4637 }
4638 
4639 // -----------------------------------------------------------------------------
4640 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4641 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, GenericImage<T5> *im5)
4642 {
4643  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4644  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4645 }
4646 
4647 // -----------------------------------------------------------------------------
4648 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4649 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4650 {
4652  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4653 }
4654 
4655 // -----------------------------------------------------------------------------
4656 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4657 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4658 {
4659  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4660  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
4661 }
4662 
4663 // -----------------------------------------------------------------------------
4664 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4665 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4666 {
4668  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4669  parallel_reduce(re, body);
4670  vf.join(body._VoxelFunc);
4671  of.join(body._OutsideFunc);
4672  } else {
4673  parallel_for(re, body);
4674  }
4675 }
4676 
4677 // -----------------------------------------------------------------------------
4678 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4679 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, GenericImage<T5> *im5)
4680 {
4681  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4682  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4683 }
4684 
4685 // -----------------------------------------------------------------------------
4686 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4687 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4688 {
4690  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4691 }
4692 
4693 // -----------------------------------------------------------------------------
4694 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4695 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4696 {
4697  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4698  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
4699 }
4700 
4701 // -----------------------------------------------------------------------------
4702 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4703 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
4704 {
4706  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4707  parallel_reduce(re, body);
4708  vf.join(body._VoxelFunc);
4709  of.join(body._OutsideFunc);
4710  } else {
4711  parallel_for(re, body);
4712  }
4713 }
4714 
4715 // -----------------------------------------------------------------------------
4716 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4717 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, GenericImage<T5> *im5)
4718 {
4719  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4720  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4721 }
4722 
4723 // -----------------------------------------------------------------------------
4724 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4725 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
4726 {
4728  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
4729 }
4730 
4731 // -----------------------------------------------------------------------------
4732 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4733 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
4734 {
4735  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4736  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
4737 }
4738 
4739 //
4740 // Image arguments by reference
4741 //
4742 
4743 // -----------------------------------------------------------------------------
4744 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4745 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4746 {
4749  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4750  parallel_reduce(re, body);
4751  vf.join(body._VoxelFunc);
4752  of.join(body._OutsideFunc);
4753  } else {
4754  parallel_for(re, body);
4755  }
4756 }
4757 
4758 // -----------------------------------------------------------------------------
4759 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4760 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4761 {
4762  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4763  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4764 }
4765 
4766 // -----------------------------------------------------------------------------
4767 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4768 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4769 {
4771  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4772 }
4773 
4774 // -----------------------------------------------------------------------------
4775 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4776 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4777 {
4778  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4779  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
4780 }
4781 
4782 // -----------------------------------------------------------------------------
4783 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4784 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4785 {
4786  if (im5.GetTSize()) {
4787  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4788  } else {
4790  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
4791  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4792  parallel_reduce(re, body);
4793  vf.join(body._VoxelFunc);
4794  of.join(body._OutsideFunc);
4795  } else {
4796  parallel_for(re, body);
4797  }
4798  }
4799 }
4800 
4801 // -----------------------------------------------------------------------------
4802 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4803 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4804 {
4805  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4806  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4807 }
4808 
4809 // -----------------------------------------------------------------------------
4810 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4811 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4812 {
4814  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
4815 }
4816 
4817 // -----------------------------------------------------------------------------
4818 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4819 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4820 {
4821  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4822  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
4823 }
4824 
4825 // -----------------------------------------------------------------------------
4826 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4827 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4828 {
4830  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4831  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4832  if (attr._dt) {
4833  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4834  } else {
4835  parallel_reduce(re, body);
4836  }
4837  vf.join(body._VoxelFunc);
4838  of.join(body._OutsideFunc);
4839  } else {
4840  if (attr._dt) {
4841  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4842  } else {
4843  parallel_for(re, body);
4844  }
4845  }
4846 }
4847 
4848 // -----------------------------------------------------------------------------
4849 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4850 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4851 {
4852  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4853  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
4854 }
4855 
4856 // -----------------------------------------------------------------------------
4857 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4858 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4859 {
4861  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
4862 }
4863 
4864 // -----------------------------------------------------------------------------
4865 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4866 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4867 {
4868  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4869  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
4870 }
4871 
4872 // -----------------------------------------------------------------------------
4873 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4874 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4875 {
4877  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4878  parallel_reduce(re, body);
4879  vf.join(body._VoxelFunc);
4880  of.join(body._OutsideFunc);
4881  } else {
4882  parallel_for(re, body);
4883  }
4884 }
4885 
4886 // -----------------------------------------------------------------------------
4887 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4888 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, GenericImage<T5> &im5)
4889 {
4890  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4891  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4892 }
4893 
4894 // -----------------------------------------------------------------------------
4895 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4896 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4897 {
4899  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4900 }
4901 
4902 // -----------------------------------------------------------------------------
4903 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4904 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4905 {
4906  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4907  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
4908 }
4909 
4910 // -----------------------------------------------------------------------------
4911 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4912 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4913 {
4915  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4916  parallel_reduce(re, body);
4917  vf.join(body._VoxelFunc);
4918  of.join(body._OutsideFunc);
4919  } else {
4920  parallel_for(re, body);
4921  }
4922 }
4923 
4924 // -----------------------------------------------------------------------------
4925 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4926 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, GenericImage<T5> &im5)
4927 {
4928  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4929  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4930 }
4931 
4932 // -----------------------------------------------------------------------------
4933 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4934 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4935 {
4937  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4938 }
4939 
4940 // -----------------------------------------------------------------------------
4941 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4942 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4943 {
4944  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4945  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
4946 }
4947 
4948 // -----------------------------------------------------------------------------
4949 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4950 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
4951 {
4953  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4954  parallel_reduce(re, body);
4955  vf.join(body._VoxelFunc);
4956  of.join(body._OutsideFunc);
4957  } else {
4958  parallel_for(re, body);
4959  }
4960 }
4961 
4962 // -----------------------------------------------------------------------------
4963 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
4964 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, GenericImage<T5> &im5)
4965 {
4966  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4967  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4968 }
4969 
4970 // -----------------------------------------------------------------------------
4971 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4972 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
4973 {
4975  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
4976 }
4977 
4978 // -----------------------------------------------------------------------------
4979 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4980 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
4981 {
4982  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
4983  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
4984 }
4985 
4986 // =============================================================================
4987 // 2 const, 3 non-const images
4988 // =============================================================================
4989 
4990 // -----------------------------------------------------------------------------
4991 /**
4992  * ForEachVoxel body for voxel function of 2 const, 3 non-const images
4993  */
4994 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
4996 {
4997  const GenericImage<T1> &im1;
4998  const GenericImage<T2> &im2;
4999  GenericImage<T3> &im3;
5000  GenericImage<T4> &im4;
5001  GenericImage<T5> &im5;
5002 
5003  /// Constructor
5005  const GenericImage<T2> &im2,
5006  GenericImage<T3> &im3,
5007  GenericImage<T4> &im4,
5008  GenericImage<T5> &im5,
5009  VoxelFunc &vf)
5010  :
5011  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
5012  {}
5013 
5014  /// Copy constructor
5016  :
5017  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
5018  {}
5019 
5020  /// Split constructor
5022  :
5023  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
5024  {}
5025 
5026  /// Process entire image
5027  void operator ()(const ImageAttributes &attr) const
5028  {
5029  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
5030  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
5031  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
5032  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
5033  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
5034 
5035  const int T = (attr._dt ? attr._t : 1);
5036 
5037  for (int l = 0; l < T; ++l)
5038  for (int k = 0; k < attr._z; ++k)
5039  for (int j = 0; j < attr._y; ++j)
5040  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
5041  // const_cast such that voxel functions need only implement
5042  // non-const operator() which is required for parallel_reduce
5043  const_cast<QuinaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4, p5);
5044  }
5045  }
5046 
5047  /// Process image region using linear index
5048  void operator ()(const blocked_range<int> &re) const
5049  {
5050  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
5051  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
5052  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
5053  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
5054  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
5055 
5056  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
5057  // const_cast such that voxel functions need only implement
5058  // non-const operator() which is required for parallel_reduce
5059  const_cast<QuinaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(im5, idx, p1, p2, p3, p4, p5);
5060  }
5061  }
5062 
5063  /// Process 2D image region
5064  void operator ()(const blocked_range2d<int> &re) const
5065  {
5066  const int bi = re.cols().begin();
5067  const int bj = re.rows().begin();
5068  const int ei = re.cols().end();
5069  const int ej = re.rows().end();
5070 
5071  const int s1 = im5.GetX() - (ei - bi);
5072 
5073  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5074  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5075  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5076  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5077  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5078 
5079  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
5080  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
5081  // const_cast such that voxel functions need only implement
5082  // non-const operator() which is required for parallel_reduce
5083  const_cast<QuinaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
5084  }
5085  }
5086 
5087  /// Process 3D image region
5088  void operator ()(const blocked_range3d<int> &re) const
5089  {
5090  const int bi = re.cols ().begin();
5091  const int bj = re.rows ().begin();
5092  const int bk = re.pages().begin();
5093  const int ei = re.cols ().end();
5094  const int ej = re.rows ().end();
5095  const int ek = re.pages().end();
5096 
5097  const int s1 = im5.GetX() - (ei - bi);
5098  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
5099 
5100  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
5101  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
5102  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
5103  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
5104  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
5105 
5106  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
5107  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
5108  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
5109  // const_cast such that voxel functions need only implement
5110  // non-const operator() which is required for parallel_reduce
5111  const_cast<QuinaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
5112  }
5113  }
5114 };
5115 
5116 // -----------------------------------------------------------------------------
5117 /**
5118  * ForEachVoxel body for inside and outside unary voxel function of 2 const, 3 non-const images
5119  */
5120 template <class T1, class T2, class T3, class T4, class T5,
5121  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
5122  class Domain = ForEachVoxelDomain::Foreground>
5123 struct QuinaryForEachVoxelIfBody_2Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
5124 {
5125  const GenericImage<T1> &im1;
5126  const GenericImage<T2> &im2;
5127  GenericImage<T3> &im3;
5128  GenericImage<T4> &im4;
5129  GenericImage<T5> &im5;
5130 
5131  /// Constructor
5133  const GenericImage<T2> &im2,
5134  GenericImage<T3> &im3,
5135  GenericImage<T4> &im4,
5136  GenericImage<T5> &im5,
5137  VoxelFunc &vf, OutsideFunc &of)
5138  :
5139  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
5140  {}
5141 
5142  /// Copy constructor
5144  :
5145  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
5146  {}
5147 
5148  /// Split constructor
5150  :
5151  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
5152  {}
5153 
5154  /// Process entire image
5155  void operator ()(const ImageAttributes &attr) const
5156  {
5157  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
5158  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
5159  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
5160  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
5161  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
5162 
5163  const int T = (attr._dt ? attr._t : 1);
5164 
5165  for (int l = 0; l < T; ++l)
5166  for (int k = 0; k < attr._z; ++k)
5167  for (int j = 0; j < attr._y; ++j)
5168  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
5169  if (Domain::IsInside(im5, i, j, k, l, p5)) {
5170  // const_cast such that voxel functions need only implement
5171  // non-const operator() which is required for parallel_reduce
5172  const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4, p5);
5173  } else const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4, p5);
5174  }
5175  }
5176 
5177  /// Process image region using linear index
5178  void operator ()(const blocked_range<int> &re) const
5179  {
5180  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
5181  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
5182  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
5183  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
5184  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
5185 
5186  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
5187  if (Domain::IsInside(im5, idx, p5)) {
5188  // const_cast such that voxel functions need only implement
5189  // non-const operator() which is required for parallel_reduce
5190  const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (im5, idx, p1, p2, p3, p4, p5);
5191  } else const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(im5, idx, p1, p2, p3, p4, p5);
5192  }
5193  }
5194 
5195  /// Process 2D image region
5196  void operator ()(const blocked_range2d<int> &re) const
5197  {
5198  const int bi = re.cols().begin();
5199  const int bj = re.rows().begin();
5200  const int ei = re.cols().end();
5201  const int ej = re.rows().end();
5202 
5203  const int s1 = im5.GetX() - (ei - bi);
5204 
5205  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5206  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5207  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5208  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5209  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5210 
5211  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
5212  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
5213  if (Domain::IsInside(im5, i, j, this->_k, this->_l, p5)) {
5214  // const_cast such that voxel functions need only implement
5215  // non-const operator() which is required for parallel_reduce
5216  const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
5217  } else const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
5218  }
5219  }
5220 
5221  /// Process 3D image region
5222  void operator ()(const blocked_range3d<int> &re) const
5223  {
5224  const int bi = re.cols ().begin();
5225  const int bj = re.rows ().begin();
5226  const int bk = re.pages().begin();
5227  const int ei = re.cols ().end();
5228  const int ej = re.rows ().end();
5229  const int ek = re.pages().end();
5230 
5231  const int s1 = im5.GetX() - (ei - bi);
5232  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
5233 
5234  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
5235  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
5236  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
5237  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
5238  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
5239 
5240  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
5241  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
5242  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
5243  if (Domain::IsInside(im5, i, j, k, this->_l, p5)) {
5244  // const_cast such that voxel functions need only implement
5245  // non-const operator() which is required for parallel_reduce
5246  const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4, p5);
5247  } else const_cast<QuinaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
5248  }
5249  }
5250 };
5251 
5252 // -----------------------------------------------------------------------------
5253 // ForEachVoxel
5254 // -----------------------------------------------------------------------------
5255 
5256 //
5257 // Image arguments by pointer
5258 //
5259 
5260 // -----------------------------------------------------------------------------
5261 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5262 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5263 {
5264  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5265  blocked_range<int> re(0, im5->GetNumberOfVoxels());
5266  body(re);
5267  vf.join(body._VoxelFunc);
5268 }
5269 
5270 // -----------------------------------------------------------------------------
5271 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5272 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5273 {
5274  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5275  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
5276 }
5277 
5278 // -----------------------------------------------------------------------------
5279 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5280 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5281 {
5282  if (im5->GetTSize()) {
5283  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
5284  } else {
5285  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5286  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
5287  body(re);
5288  vf.join(body._VoxelFunc);
5289  }
5290 }
5291 
5292 // -----------------------------------------------------------------------------
5293 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5294 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5295 {
5296  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5297  ForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
5298 }
5299 
5300 // -----------------------------------------------------------------------------
5301 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5302 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5303 {
5304  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5305  body(attr);
5306  vf.join(body._VoxelFunc);
5307 }
5308 
5309 // -----------------------------------------------------------------------------
5310 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5311 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5312 {
5313  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5314  ForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
5315 }
5316 
5317 // -----------------------------------------------------------------------------
5318 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5319 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5320 {
5321  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5322  body(re);
5323  vf.join(body._VoxelFunc);
5324 }
5325 
5326 // -----------------------------------------------------------------------------
5327 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5328 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5329 {
5330  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5331  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
5332 }
5333 
5334 // -----------------------------------------------------------------------------
5335 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5336 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5337 {
5338  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5339  body(re);
5340  vf.join(body._VoxelFunc);
5341 }
5342 
5343 // -----------------------------------------------------------------------------
5344 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5345 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5346 {
5347  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5348  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
5349 }
5350 
5351 // -----------------------------------------------------------------------------
5352 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5353 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5354 {
5355  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5356  body(re);
5357  vf.join(body._VoxelFunc);
5358 }
5359 
5360 // -----------------------------------------------------------------------------
5361 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5362 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5363 {
5364  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5365  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
5366 }
5367 
5368 //
5369 // Image arguments by reference
5370 //
5371 
5372 // -----------------------------------------------------------------------------
5373 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5374 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5375 {
5376  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
5378  body(re);
5379  vf.join(body._VoxelFunc);
5380 }
5381 
5382 // -----------------------------------------------------------------------------
5383 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5384 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5385 {
5386  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5387  ForEachScalar(im1, im2, im3, im4, im5, vf);
5388 }
5389 
5390 // -----------------------------------------------------------------------------
5391 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5392 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5393 {
5394  if (im5.GetTSize()) {
5395  ForEachScalar(im1, im2, im3, im4, im5, vf);
5396  } else {
5397  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
5398  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
5399  body(re);
5400  vf.join(body._VoxelFunc);
5401  }
5402 }
5403 
5404 // -----------------------------------------------------------------------------
5405 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5406 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5407 {
5408  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5409  ForEachVoxel(im1, im2, im3, im4, im5, vf);
5410 }
5411 
5412 // -----------------------------------------------------------------------------
5413 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5414 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5415 {
5416  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
5417  body(attr);
5418  vf.join(body._VoxelFunc);
5419 }
5420 
5421 // -----------------------------------------------------------------------------
5422 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5423 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5424 {
5425  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5426  ForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
5427 }
5428 
5429 // -----------------------------------------------------------------------------
5430 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5431 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5432 {
5433  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
5434  body(re);
5435  vf.join(body._VoxelFunc);
5436 }
5437 
5438 // -----------------------------------------------------------------------------
5439 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5440 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5441 {
5442  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5443  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
5444 }
5445 
5446 // -----------------------------------------------------------------------------
5447 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5448 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5449 {
5450  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
5451  body(re);
5452  vf.join(body._VoxelFunc);
5453 }
5454 
5455 // -----------------------------------------------------------------------------
5456 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5457 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5458 {
5459  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5460  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
5461 }
5462 
5463 // -----------------------------------------------------------------------------
5464 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5465 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5466 {
5467  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
5468  body(re);
5469  vf.join(body._VoxelFunc);
5470 }
5471 
5472 // -----------------------------------------------------------------------------
5473 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5474 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5475 {
5476  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5477  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
5478 }
5479 
5480 // -----------------------------------------------------------------------------
5481 // ForEachVoxelIf
5482 // -----------------------------------------------------------------------------
5483 
5484 //
5485 // Image arguments by pointer
5486 //
5487 
5488 // -----------------------------------------------------------------------------
5489 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5490 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
5491 {
5493  blocked_range<int> re(0, im5->GetNumberOfVoxels());
5494  body(re);
5495  vf.join(body._VoxelFunc);
5496  of.join(body._OutsideFunc);
5497 }
5498 
5499 // -----------------------------------------------------------------------------
5500 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5501 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5502 {
5503  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5504  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
5505 }
5506 
5507 // -----------------------------------------------------------------------------
5508 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5509 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5510 {
5512  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
5513 }
5514 
5515 // -----------------------------------------------------------------------------
5516 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5517 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5518 {
5519  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5520  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
5521 }
5522 
5523 // -----------------------------------------------------------------------------
5524 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5525 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
5526 {
5527  if (im5->GetTSize()) {
5528  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
5529  } else {
5531  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
5532  body(re);
5533  vf.join(body._VoxelFunc);
5534  of.join(body._OutsideFunc);
5535  }
5536 }
5537 
5538 // -----------------------------------------------------------------------------
5539 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5540 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5541 {
5542  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5543  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
5544 }
5545 
5546 // -----------------------------------------------------------------------------
5547 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5548 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5549 {
5551  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
5552 }
5553 
5554 // -----------------------------------------------------------------------------
5555 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5556 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5557 {
5558  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5559  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
5560 }
5561 
5562 // -----------------------------------------------------------------------------
5563 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5564 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
5565 {
5567  body(attr);
5568  vf.join(body._VoxelFunc);
5569  of.join(body._OutsideFunc);
5570 }
5571 
5572 // -----------------------------------------------------------------------------
5573 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5574 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5575 {
5576  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5577  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
5578 }
5579 
5580 // -----------------------------------------------------------------------------
5581 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5582 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5583 {
5585  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
5586 }
5587 
5588 // -----------------------------------------------------------------------------
5589 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5590 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5591 {
5592  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5593  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
5594 }
5595 
5596 // -----------------------------------------------------------------------------
5597 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5598 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
5599 {
5601  body(re);
5602  vf.join(body._VoxelFunc);
5603  of.join(body._OutsideFunc);
5604 }
5605 
5606 // -----------------------------------------------------------------------------
5607 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5608 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, GenericImage<T5> *im5)
5609 {
5610  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5611  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
5612 }
5613 
5614 // -----------------------------------------------------------------------------
5615 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5616 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
5617 {
5619  body(re);
5620  vf.join(body._VoxelFunc);
5621  of.join(body._OutsideFunc);
5622 }
5623 
5624 // -----------------------------------------------------------------------------
5625 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5626 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, GenericImage<T5> *im5)
5627 {
5628  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5629  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
5630 }
5631 
5632 // -----------------------------------------------------------------------------
5633 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5634 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5635 {
5637  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
5638 }
5639 
5640 // -----------------------------------------------------------------------------
5641 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5642 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5643 {
5644  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5645  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
5646 }
5647 
5648 // -----------------------------------------------------------------------------
5649 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5650 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
5651 {
5653  body(re);
5654  vf.join(body._VoxelFunc);
5655  of.join(body._OutsideFunc);
5656 }
5657 
5658 // -----------------------------------------------------------------------------
5659 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5660 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, GenericImage<T5> *im5)
5661 {
5662  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5663  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
5664 }
5665 
5666 // -----------------------------------------------------------------------------
5667 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5668 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5669 {
5671  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
5672 }
5673 
5674 // -----------------------------------------------------------------------------
5675 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5676 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5677 {
5678  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5679  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
5680 }
5681 
5682 //
5683 // Image arguments by reference
5684 //
5685 
5686 // -----------------------------------------------------------------------------
5687 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5688 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
5689 {
5692  body(re);
5693  vf.join(body._VoxelFunc);
5694  of.join(body._OutsideFunc);
5695 }
5696 
5697 // -----------------------------------------------------------------------------
5698 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5699 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5700 {
5701  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5702  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
5703 }
5704 
5705 // -----------------------------------------------------------------------------
5706 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5707 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5708 {
5710  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
5711 }
5712 
5713 // -----------------------------------------------------------------------------
5714 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5715 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5716 {
5717  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5718  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
5719 }
5720 
5721 // -----------------------------------------------------------------------------
5722 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5723 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
5724 {
5725  if (im5.GetTSize()) {
5726  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
5727  } else {
5729  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
5730  body(re);
5731  vf.join(body._VoxelFunc);
5732  of.join(body._OutsideFunc);
5733  }
5734 }
5735 
5736 // -----------------------------------------------------------------------------
5737 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5738 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5739 {
5740  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5741  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
5742 }
5743 
5744 // -----------------------------------------------------------------------------
5745 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5746 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5747 {
5749  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
5750 }
5751 
5752 // -----------------------------------------------------------------------------
5753 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5754 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5755 {
5756  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5757  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
5758 }
5759 
5760 // -----------------------------------------------------------------------------
5761 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5762 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
5763 {
5765  body(attr);
5766  vf.join(body._VoxelFunc);
5767  of.join(body._OutsideFunc);
5768 }
5769 
5770 // -----------------------------------------------------------------------------
5771 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5772 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5773 {
5774  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5775  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
5776 }
5777 
5778 // -----------------------------------------------------------------------------
5779 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5780 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5781 {
5783  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
5784 }
5785 
5786 // -----------------------------------------------------------------------------
5787 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5788 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5789 {
5790  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5791  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
5792 }
5793 
5794 // -----------------------------------------------------------------------------
5795 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5796 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
5797 {
5799  body(re);
5800  vf.join(body._VoxelFunc);
5801  of.join(body._OutsideFunc);
5802 }
5803 
5804 // -----------------------------------------------------------------------------
5805 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5806 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, GenericImage<T5> &im5)
5807 {
5808  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5809  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
5810 }
5811 
5812 // -----------------------------------------------------------------------------
5813 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5814 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
5815 {
5817  body(re);
5818  vf.join(body._VoxelFunc);
5819  of.join(body._OutsideFunc);
5820 }
5821 
5822 // -----------------------------------------------------------------------------
5823 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5824 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, GenericImage<T5> &im5)
5825 {
5826  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5827  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
5828 }
5829 
5830 // -----------------------------------------------------------------------------
5831 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5832 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5833 {
5835  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
5836 }
5837 
5838 // -----------------------------------------------------------------------------
5839 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5840 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5841 {
5842  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5843  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
5844 }
5845 
5846 // -----------------------------------------------------------------------------
5847 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5848 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
5849 {
5851  body(re);
5852  vf.join(body._VoxelFunc);
5853  of.join(body._OutsideFunc);
5854 }
5855 
5856 // -----------------------------------------------------------------------------
5857 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
5858 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, GenericImage<T5> &im5)
5859 {
5860  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5861  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
5862 }
5863 
5864 // -----------------------------------------------------------------------------
5865 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5866 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
5867 {
5869  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
5870 }
5871 
5872 // -----------------------------------------------------------------------------
5873 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5874 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
5875 {
5876  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5877  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
5878 }
5879 
5880 // -----------------------------------------------------------------------------
5881 // ParallelForEachVoxel
5882 // -----------------------------------------------------------------------------
5883 
5884 //
5885 // Image arguments by pointer
5886 //
5887 
5888 // -----------------------------------------------------------------------------
5889 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5890 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5891 {
5892  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5893  blocked_range<int> re(0, im5->GetNumberOfVoxels());
5894  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5895  else parallel_for (re, body);
5896 }
5897 
5898 // -----------------------------------------------------------------------------
5899 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5900 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5901 {
5902  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5903  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
5904 }
5905 
5906 // -----------------------------------------------------------------------------
5907 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5908 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5909 {
5910  if (im5->GetTSize()) {
5911  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
5912  } else {
5913  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5914  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
5915  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5916  else parallel_for (re, body);
5917  }
5918 }
5919 
5920 // -----------------------------------------------------------------------------
5921 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5922 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5923 {
5924  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5925  ParallelForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
5926 }
5927 
5928 // -----------------------------------------------------------------------------
5929 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5930 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5931 {
5932  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5933  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
5934  if (VoxelFunc::IsReduction()) {
5935  if (attr._dt) {
5936  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
5937  } else {
5938  parallel_reduce(re, body);
5939  }
5940  vf.join(body._VoxelFunc);
5941  } else {
5942  if (attr._dt) {
5943  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
5944  } else {
5945  parallel_for(re, body);
5946  }
5947  }
5948 }
5949 
5950 // -----------------------------------------------------------------------------
5951 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5952 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5953 {
5954  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5955  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
5956 }
5957 
5958 // -----------------------------------------------------------------------------
5959 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5960 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5961 {
5962  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5963  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5964  else parallel_for (re, body);
5965 }
5966 
5967 // -----------------------------------------------------------------------------
5968 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5969 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5970 {
5971  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5972  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
5973 }
5974 
5975 // -----------------------------------------------------------------------------
5976 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5977 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5978 {
5979  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5980  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5981  else parallel_for (re, body);
5982 }
5983 
5984 // -----------------------------------------------------------------------------
5985 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5986 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
5987 {
5988  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
5989  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
5990 }
5991 
5992 // -----------------------------------------------------------------------------
5993 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
5994 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
5995 {
5996  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
5997  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5998  else parallel_for (re, body);
5999 }
6000 
6001 // -----------------------------------------------------------------------------
6002 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6003 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6004 {
6005  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6006  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
6007 }
6008 
6009 //
6010 // Image arguments by reference
6011 //
6012 
6013 // -----------------------------------------------------------------------------
6014 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6015 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6016 {
6017  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
6019  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6020  else parallel_for (re, body);
6021 }
6022 
6023 // -----------------------------------------------------------------------------
6024 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6025 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6026 {
6027  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6028  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
6029 }
6030 
6031 // -----------------------------------------------------------------------------
6032 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6033 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6034 {
6035  if (im5.GetTSize()) {
6036  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
6037  } else {
6038  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
6039  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
6040  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6041  else parallel_for (re, body);
6042  }
6043 }
6044 
6045 // -----------------------------------------------------------------------------
6046 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6047 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6048 {
6049  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6050  ParallelForEachVoxel(im1, im2, im3, im4, im5, vf);
6051 }
6052 
6053 // -----------------------------------------------------------------------------
6054 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6055 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6056 {
6057  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
6058  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6059  if (VoxelFunc::IsReduction()) {
6060  if (attr._dt) {
6061  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6062  } else {
6063  parallel_reduce(re, body);
6064  }
6065  vf.join(body._VoxelFunc);
6066  } else {
6067  if (attr._dt) {
6068  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6069  } else {
6070  parallel_for(re, body);
6071  }
6072  }
6073 }
6074 
6075 // -----------------------------------------------------------------------------
6076 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6077 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6078 {
6079  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6080  ParallelForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
6081 }
6082 
6083 // -----------------------------------------------------------------------------
6084 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6085 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6086 {
6087  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
6088  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6089  else parallel_for (re, body);
6090 }
6091 
6092 // -----------------------------------------------------------------------------
6093 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6094 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6095 {
6096  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6097  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
6098 }
6099 
6100 // -----------------------------------------------------------------------------
6101 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6102 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6103 {
6104  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
6105  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6106  else parallel_for (re, body);
6107 }
6108 
6109 // -----------------------------------------------------------------------------
6110 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6111 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6112 {
6113  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6114  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
6115 }
6116 
6117 // -----------------------------------------------------------------------------
6118 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6119 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6120 {
6121  QuinaryForEachVoxelBody_2Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
6122  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6123  else parallel_for (re, body);
6124 }
6125 
6126 // -----------------------------------------------------------------------------
6127 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6128 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6129 {
6130  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6131  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
6132 }
6133 
6134 // -----------------------------------------------------------------------------
6135 // ParallelForEachVoxelIf
6136 // -----------------------------------------------------------------------------
6137 
6138 //
6139 // Image arguments by pointer
6140 //
6141 
6142 // -----------------------------------------------------------------------------
6143 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6144 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
6145 {
6147  blocked_range<int> re(0, im5->GetNumberOfVoxels());
6148  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6149  parallel_reduce(re, body);
6150  vf.join(body._VoxelFunc);
6151  of.join(body._OutsideFunc);
6152  } else {
6153  parallel_for(re, body);
6154  }
6155 }
6156 
6157 // -----------------------------------------------------------------------------
6158 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6159 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6160 {
6161  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6162  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
6163 }
6164 
6165 // -----------------------------------------------------------------------------
6166 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6167 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6168 {
6170  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
6171 }
6172 
6173 // -----------------------------------------------------------------------------
6174 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6175 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6176 {
6177  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6178  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
6179 }
6180 
6181 // -----------------------------------------------------------------------------
6182 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6183 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
6184 {
6185  if (im5->GetTSize()) {
6186  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
6187  } else {
6189  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
6190  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6191  parallel_reduce(re, body);
6192  vf.join(body._VoxelFunc);
6193  of.join(body._OutsideFunc);
6194  } else {
6195  parallel_for(re, body);
6196  }
6197  }
6198 }
6199 
6200 // -----------------------------------------------------------------------------
6201 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6202 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6203 {
6204  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6205  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
6206 }
6207 
6208 // -----------------------------------------------------------------------------
6209 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6210 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6211 {
6213  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
6214 }
6215 
6216 // -----------------------------------------------------------------------------
6217 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6218 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6219 {
6220  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6221  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
6222 }
6223 
6224 // -----------------------------------------------------------------------------
6225 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6226 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
6227 {
6229  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6230  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6231  if (attr._dt) {
6232  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6233  } else {
6234  parallel_reduce(re, body);
6235  }
6236  vf.join(body._VoxelFunc);
6237  of.join(body._OutsideFunc);
6238  } else {
6239  if (attr._dt) {
6240  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6241  } else {
6242  parallel_for(re, body);
6243  }
6244  }
6245 }
6246 
6247 // -----------------------------------------------------------------------------
6248 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6249 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6250 {
6251  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6252  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
6253 }
6254 
6255 // -----------------------------------------------------------------------------
6256 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6257 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6258 {
6260  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
6261 }
6262 
6263 // -----------------------------------------------------------------------------
6264 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6265 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6266 {
6267  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6268  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
6269 }
6270 
6271 // -----------------------------------------------------------------------------
6272 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6273 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
6274 {
6276  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6277  parallel_reduce(re, body);
6278  vf.join(body._VoxelFunc);
6279  of.join(body._OutsideFunc);
6280  } else {
6281  parallel_for(re, body);
6282  }
6283 }
6284 
6285 // -----------------------------------------------------------------------------
6286 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6287 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, GenericImage<T5> *im5)
6288 {
6289  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6290  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
6291 }
6292 
6293 // -----------------------------------------------------------------------------
6294 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6295 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6296 {
6298  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
6299 }
6300 
6301 // -----------------------------------------------------------------------------
6302 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6303 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6304 {
6305  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6306  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
6307 }
6308 
6309 // -----------------------------------------------------------------------------
6310 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6311 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
6312 {
6314  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6315  parallel_reduce(re, body);
6316  vf.join(body._VoxelFunc);
6317  of.join(body._OutsideFunc);
6318  } else {
6319  parallel_for(re, body);
6320  }
6321 }
6322 
6323 // -----------------------------------------------------------------------------
6324 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6325 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, GenericImage<T5> *im5)
6326 {
6327  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6328  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
6329 }
6330 
6331 // -----------------------------------------------------------------------------
6332 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6333 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6334 {
6336  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
6337 }
6338 
6339 // -----------------------------------------------------------------------------
6340 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6341 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6342 {
6343  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6344  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
6345 }
6346 
6347 // -----------------------------------------------------------------------------
6348 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6349 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
6350 {
6352  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6353  parallel_reduce(re, body);
6354  vf.join(body._VoxelFunc);
6355  of.join(body._OutsideFunc);
6356  } else {
6357  parallel_for(re, body);
6358  }
6359 }
6360 
6361 // -----------------------------------------------------------------------------
6362 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6363 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, GenericImage<T5> *im5)
6364 {
6365  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6366  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
6367 }
6368 
6369 // -----------------------------------------------------------------------------
6370 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6371 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6372 {
6374  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
6375 }
6376 
6377 // -----------------------------------------------------------------------------
6378 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6379 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6380 {
6381  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6382  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
6383 }
6384 
6385 //
6386 // Image arguments by reference
6387 //
6388 
6389 // -----------------------------------------------------------------------------
6390 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6391 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
6392 {
6395  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6396  parallel_reduce(re, body);
6397  vf.join(body._VoxelFunc);
6398  of.join(body._OutsideFunc);
6399  } else {
6400  parallel_for(re, body);
6401  }
6402 }
6403 
6404 // -----------------------------------------------------------------------------
6405 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6406 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6407 {
6408  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6409  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
6410 }
6411 
6412 // -----------------------------------------------------------------------------
6413 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6414 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6415 {
6417  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
6418 }
6419 
6420 // -----------------------------------------------------------------------------
6421 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6422 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6423 {
6424  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6425  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
6426 }
6427 
6428 // -----------------------------------------------------------------------------
6429 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6430 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
6431 {
6432  if (im5.GetTSize()) {
6433  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
6434  } else {
6436  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
6437  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6438  parallel_reduce(re, body);
6439  vf.join(body._VoxelFunc);
6440  of.join(body._OutsideFunc);
6441  } else {
6442  parallel_for(re, body);
6443  }
6444  }
6445 }
6446 
6447 // -----------------------------------------------------------------------------
6448 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6449 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6450 {
6451  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6452  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
6453 }
6454 
6455 // -----------------------------------------------------------------------------
6456 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6457 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6458 {
6460  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
6461 }
6462 
6463 // -----------------------------------------------------------------------------
6464 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6465 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6466 {
6467  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6468  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
6469 }
6470 
6471 // -----------------------------------------------------------------------------
6472 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6473 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
6474 {
6476  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6477  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6478  if (attr._dt) {
6479  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6480  } else {
6481  parallel_reduce(re, body);
6482  }
6483  vf.join(body._VoxelFunc);
6484  of.join(body._OutsideFunc);
6485  } else {
6486  if (attr._dt) {
6487  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6488  } else {
6489  parallel_for(re, body);
6490  }
6491  }
6492 }
6493 
6494 // -----------------------------------------------------------------------------
6495 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6496 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6497 {
6498  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6499  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
6500 }
6501 
6502 // -----------------------------------------------------------------------------
6503 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6504 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6505 {
6507  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
6508 }
6509 
6510 // -----------------------------------------------------------------------------
6511 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6512 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6513 {
6514  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6515  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
6516 }
6517 
6518 // -----------------------------------------------------------------------------
6519 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6520 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
6521 {
6523  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6524  parallel_reduce(re, body);
6525  vf.join(body._VoxelFunc);
6526  of.join(body._OutsideFunc);
6527  } else {
6528  parallel_for(re, body);
6529  }
6530 }
6531 
6532 // -----------------------------------------------------------------------------
6533 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6534 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, GenericImage<T5> &im5)
6535 {
6536  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6537  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
6538 }
6539 
6540 // -----------------------------------------------------------------------------
6541 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6542 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6543 {
6545  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
6546 }
6547 
6548 // -----------------------------------------------------------------------------
6549 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6550 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6551 {
6552  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6553  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
6554 }
6555 
6556 // -----------------------------------------------------------------------------
6557 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6558 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
6559 {
6561  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6562  parallel_reduce(re, body);
6563  vf.join(body._VoxelFunc);
6564  of.join(body._OutsideFunc);
6565  } else {
6566  parallel_for(re, body);
6567  }
6568 }
6569 
6570 // -----------------------------------------------------------------------------
6571 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6572 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, GenericImage<T5> &im5)
6573 {
6574  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6575  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
6576 }
6577 
6578 // -----------------------------------------------------------------------------
6579 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6580 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6581 {
6583  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
6584 }
6585 
6586 // -----------------------------------------------------------------------------
6587 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6588 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6589 {
6590  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6591  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
6592 }
6593 
6594 // -----------------------------------------------------------------------------
6595 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6596 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
6597 {
6599  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6600  parallel_reduce(re, body);
6601  vf.join(body._VoxelFunc);
6602  of.join(body._OutsideFunc);
6603  } else {
6604  parallel_for(re, body);
6605  }
6606 }
6607 
6608 // -----------------------------------------------------------------------------
6609 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
6610 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, GenericImage<T5> &im5)
6611 {
6612  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6613  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
6614 }
6615 
6616 // -----------------------------------------------------------------------------
6617 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6618 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
6619 {
6621  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
6622 }
6623 
6624 // -----------------------------------------------------------------------------
6625 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6626 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
6627 {
6628  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6629  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
6630 }
6631 
6632 // =============================================================================
6633 // 1 const, 4 non-const images
6634 // =============================================================================
6635 
6636 // -----------------------------------------------------------------------------
6637 /**
6638  * ForEachVoxel body for voxel function of 1 const, 4 non-const images
6639  */
6640 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6642 {
6643  const GenericImage<T1> &im1;
6644  GenericImage<T2> &im2;
6645  GenericImage<T3> &im3;
6646  GenericImage<T4> &im4;
6647  GenericImage<T5> &im5;
6648 
6649  /// Constructor
6651  GenericImage<T2> &im2,
6652  GenericImage<T3> &im3,
6653  GenericImage<T4> &im4,
6654  GenericImage<T5> &im5,
6655  VoxelFunc &vf)
6656  :
6657  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
6658  {}
6659 
6660  /// Copy constructor
6662  :
6663  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
6664  {}
6665 
6666  /// Split constructor
6668  :
6669  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
6670  {}
6671 
6672  /// Process entire image
6673  void operator ()(const ImageAttributes &attr) const
6674  {
6675  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
6676  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
6677  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
6678  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
6679  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
6680 
6681  const int T = (attr._dt ? attr._t : 1);
6682 
6683  for (int l = 0; l < T; ++l)
6684  for (int k = 0; k < attr._z; ++k)
6685  for (int j = 0; j < attr._y; ++j)
6686  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
6687  // const_cast such that voxel functions need only implement
6688  // non-const operator() which is required for parallel_reduce
6689  const_cast<QuinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4, p5);
6690  }
6691  }
6692 
6693  /// Process image region using linear index
6694  void operator ()(const blocked_range<int> &re) const
6695  {
6696  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
6697  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
6698  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
6699  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
6700  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
6701 
6702  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
6703  // const_cast such that voxel functions need only implement
6704  // non-const operator() which is required for parallel_reduce
6705  const_cast<QuinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(im5, idx, p1, p2, p3, p4, p5);
6706  }
6707  }
6708 
6709  /// Process 2D image region
6710  void operator ()(const blocked_range2d<int> &re) const
6711  {
6712  const int bi = re.cols().begin();
6713  const int bj = re.rows().begin();
6714  const int ei = re.cols().end();
6715  const int ej = re.rows().end();
6716 
6717  const int s1 = im5.GetX() - (ei - bi);
6718 
6719  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6720  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6721  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6722  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6723  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6724 
6725  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
6726  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
6727  // const_cast such that voxel functions need only implement
6728  // non-const operator() which is required for parallel_reduce
6729  const_cast<QuinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
6730  }
6731  }
6732 
6733  /// Process 3D image region
6734  void operator ()(const blocked_range3d<int> &re) const
6735  {
6736  const int bi = re.cols ().begin();
6737  const int bj = re.rows ().begin();
6738  const int bk = re.pages().begin();
6739  const int ei = re.cols ().end();
6740  const int ej = re.rows ().end();
6741  const int ek = re.pages().end();
6742 
6743  const int s1 = im5.GetX() - (ei - bi);
6744  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
6745 
6746  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
6747  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
6748  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
6749  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
6750  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
6751 
6752  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
6753  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
6754  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
6755  // const_cast such that voxel functions need only implement
6756  // non-const operator() which is required for parallel_reduce
6757  const_cast<QuinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
6758  }
6759  }
6760 };
6761 
6762 // -----------------------------------------------------------------------------
6763 /**
6764  * ForEachVoxel body for inside and outside unary voxel function of 1 const, 4 non-const images
6765  */
6766 template <class T1, class T2, class T3, class T4, class T5,
6767  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
6768  class Domain = ForEachVoxelDomain::Foreground>
6769 struct QuinaryForEachVoxelIfBody_1Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
6770 {
6771  const GenericImage<T1> &im1;
6772  GenericImage<T2> &im2;
6773  GenericImage<T3> &im3;
6774  GenericImage<T4> &im4;
6775  GenericImage<T5> &im5;
6776 
6777  /// Constructor
6779  GenericImage<T2> &im2,
6780  GenericImage<T3> &im3,
6781  GenericImage<T4> &im4,
6782  GenericImage<T5> &im5,
6783  VoxelFunc &vf, OutsideFunc &of)
6784  :
6785  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
6786  {}
6787 
6788  /// Copy constructor
6790  :
6791  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
6792  {}
6793 
6794  /// Split constructor
6796  :
6797  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
6798  {}
6799 
6800  /// Process entire image
6801  void operator ()(const ImageAttributes &attr) const
6802  {
6803  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
6804  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
6805  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
6806  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
6807  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
6808 
6809  const int T = (attr._dt ? attr._t : 1);
6810 
6811  for (int l = 0; l < T; ++l)
6812  for (int k = 0; k < attr._z; ++k)
6813  for (int j = 0; j < attr._y; ++j)
6814  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
6815  if (Domain::IsInside(im5, i, j, k, l, p5)) {
6816  // const_cast such that voxel functions need only implement
6817  // non-const operator() which is required for parallel_reduce
6818  const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4, p5);
6819  } else const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4, p5);
6820  }
6821  }
6822 
6823  /// Process image region using linear index
6824  void operator ()(const blocked_range<int> &re) const
6825  {
6826  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
6827  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
6828  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
6829  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
6830  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
6831 
6832  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
6833  if (Domain::IsInside(im5, idx, p5)) {
6834  // const_cast such that voxel functions need only implement
6835  // non-const operator() which is required for parallel_reduce
6836  const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (im5, idx, p1, p2, p3, p4, p5);
6837  } else const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(im5, idx, p1, p2, p3, p4, p5);
6838  }
6839  }
6840 
6841  /// Process 2D image region
6842  void operator ()(const blocked_range2d<int> &re) const
6843  {
6844  const int bi = re.cols().begin();
6845  const int bj = re.rows().begin();
6846  const int ei = re.cols().end();
6847  const int ej = re.rows().end();
6848 
6849  const int s1 = im5.GetX() - (ei - bi);
6850 
6851  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6852  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6853  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6854  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6855  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
6856 
6857  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
6858  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
6859  if (Domain::IsInside(im5, i, j, this->_k, this->_l, p5)) {
6860  // const_cast such that voxel functions need only implement
6861  // non-const operator() which is required for parallel_reduce
6862  const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
6863  } else const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
6864  }
6865  }
6866 
6867  /// Process 3D image region
6868  void operator ()(const blocked_range3d<int> &re) const
6869  {
6870  const int bi = re.cols ().begin();
6871  const int bj = re.rows ().begin();
6872  const int bk = re.pages().begin();
6873  const int ei = re.cols ().end();
6874  const int ej = re.rows ().end();
6875  const int ek = re.pages().end();
6876 
6877  const int s1 = im5.GetX() - (ei - bi);
6878  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
6879 
6880  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
6881  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
6882  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
6883  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
6884  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
6885 
6886  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
6887  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
6888  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
6889  if (Domain::IsInside(im5, i, j, k, this->_l, p5)) {
6890  // const_cast such that voxel functions need only implement
6891  // non-const operator() which is required for parallel_reduce
6892  const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4, p5);
6893  } else const_cast<QuinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
6894  }
6895  }
6896 };
6897 
6898 // -----------------------------------------------------------------------------
6899 // ForEachVoxel
6900 // -----------------------------------------------------------------------------
6901 
6902 //
6903 // Image arguments by pointer
6904 //
6905 
6906 // -----------------------------------------------------------------------------
6907 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6908 void ForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6909 {
6910  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
6911  blocked_range<int> re(0, im5->GetNumberOfVoxels());
6912  body(re);
6913  vf.join(body._VoxelFunc);
6914 }
6915 
6916 // -----------------------------------------------------------------------------
6917 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6918 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6919 {
6920  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6921  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
6922 }
6923 
6924 // -----------------------------------------------------------------------------
6925 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6926 void ForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6927 {
6928  if (im5->GetTSize()) {
6929  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
6930  } else {
6931  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
6932  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
6933  body(re);
6934  vf.join(body._VoxelFunc);
6935  }
6936 }
6937 
6938 // -----------------------------------------------------------------------------
6939 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6940 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6941 {
6942  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6943  ForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
6944 }
6945 
6946 // -----------------------------------------------------------------------------
6947 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6948 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6949 {
6950  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
6951  body(attr);
6952  vf.join(body._VoxelFunc);
6953 }
6954 
6955 // -----------------------------------------------------------------------------
6956 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6957 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6958 {
6959  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6960  ForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
6961 }
6962 
6963 // -----------------------------------------------------------------------------
6964 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6965 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6966 {
6967  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
6968  body(re);
6969  vf.join(body._VoxelFunc);
6970 }
6971 
6972 // -----------------------------------------------------------------------------
6973 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6974 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6975 {
6976  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6977  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
6978 }
6979 
6980 // -----------------------------------------------------------------------------
6981 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6982 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
6983 {
6984  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
6985  body(re);
6986  vf.join(body._VoxelFunc);
6987 }
6988 
6989 // -----------------------------------------------------------------------------
6990 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6991 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
6992 {
6993  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
6994  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
6995 }
6996 
6997 // -----------------------------------------------------------------------------
6998 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
6999 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7000 {
7001  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7002  body(re);
7003  vf.join(body._VoxelFunc);
7004 }
7005 
7006 // -----------------------------------------------------------------------------
7007 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7008 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7009 {
7010  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7011  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
7012 }
7013 
7014 //
7015 // Image arguments by reference
7016 //
7017 
7018 // -----------------------------------------------------------------------------
7019 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7020 void ForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7021 {
7022  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7024  body(re);
7025  vf.join(body._VoxelFunc);
7026 }
7027 
7028 // -----------------------------------------------------------------------------
7029 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7030 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7031 {
7032  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7033  ForEachScalar(im1, im2, im3, im4, im5, vf);
7034 }
7035 
7036 // -----------------------------------------------------------------------------
7037 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7038 void ForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7039 {
7040  if (im5.GetTSize()) {
7041  ForEachScalar(im1, im2, im3, im4, im5, vf);
7042  } else {
7043  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7044  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
7045  body(re);
7046  vf.join(body._VoxelFunc);
7047  }
7048 }
7049 
7050 // -----------------------------------------------------------------------------
7051 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7052 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7053 {
7054  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7055  ForEachVoxel(im1, im2, im3, im4, im5, vf);
7056 }
7057 
7058 // -----------------------------------------------------------------------------
7059 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7060 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7061 {
7062  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7063  body(attr);
7064  vf.join(body._VoxelFunc);
7065 }
7066 
7067 // -----------------------------------------------------------------------------
7068 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7069 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7070 {
7071  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7072  ForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
7073 }
7074 
7075 // -----------------------------------------------------------------------------
7076 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7077 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7078 {
7079  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7080  body(re);
7081  vf.join(body._VoxelFunc);
7082 }
7083 
7084 // -----------------------------------------------------------------------------
7085 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7086 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7087 {
7088  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7089  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
7090 }
7091 
7092 // -----------------------------------------------------------------------------
7093 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7094 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7095 {
7096  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7097  body(re);
7098  vf.join(body._VoxelFunc);
7099 }
7100 
7101 // -----------------------------------------------------------------------------
7102 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7103 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7104 {
7105  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7106  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
7107 }
7108 
7109 // -----------------------------------------------------------------------------
7110 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7111 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7112 {
7113  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7114  body(re);
7115  vf.join(body._VoxelFunc);
7116 }
7117 
7118 // -----------------------------------------------------------------------------
7119 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7120 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7121 {
7122  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7123  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
7124 }
7125 
7126 // -----------------------------------------------------------------------------
7127 // ForEachVoxelIf
7128 // -----------------------------------------------------------------------------
7129 
7130 //
7131 // Image arguments by pointer
7132 //
7133 
7134 // -----------------------------------------------------------------------------
7135 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7136 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7137 {
7139  blocked_range<int> re(0, im5->GetNumberOfVoxels());
7140  body(re);
7141  vf.join(body._VoxelFunc);
7142  of.join(body._OutsideFunc);
7143 }
7144 
7145 // -----------------------------------------------------------------------------
7146 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7147 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7148 {
7149  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7150  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7151 }
7152 
7153 // -----------------------------------------------------------------------------
7154 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7155 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7156 {
7158  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7159 }
7160 
7161 // -----------------------------------------------------------------------------
7162 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7163 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7164 {
7165  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7166  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
7167 }
7168 
7169 // -----------------------------------------------------------------------------
7170 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7171 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7172 {
7173  if (im5->GetTSize()) {
7174  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7175  } else {
7177  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
7178  body(re);
7179  vf.join(body._VoxelFunc);
7180  of.join(body._OutsideFunc);
7181  }
7182 }
7183 
7184 // -----------------------------------------------------------------------------
7185 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7186 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7187 {
7188  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7189  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7190 }
7191 
7192 // -----------------------------------------------------------------------------
7193 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7194 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7195 {
7197  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7198 }
7199 
7200 // -----------------------------------------------------------------------------
7201 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7202 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7203 {
7204  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7205  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
7206 }
7207 
7208 // -----------------------------------------------------------------------------
7209 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7210 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7211 {
7213  body(attr);
7214  vf.join(body._VoxelFunc);
7215  of.join(body._OutsideFunc);
7216 }
7217 
7218 // -----------------------------------------------------------------------------
7219 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7220 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7221 {
7222  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7223  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
7224 }
7225 
7226 // -----------------------------------------------------------------------------
7227 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7228 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7229 {
7231  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
7232 }
7233 
7234 // -----------------------------------------------------------------------------
7235 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7236 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7237 {
7238  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7239  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
7240 }
7241 
7242 // -----------------------------------------------------------------------------
7243 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7244 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7245 {
7247  body(re);
7248  vf.join(body._VoxelFunc);
7249  of.join(body._OutsideFunc);
7250 }
7251 
7252 // -----------------------------------------------------------------------------
7253 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7254 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7255 {
7256  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7257  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7258 }
7259 
7260 // -----------------------------------------------------------------------------
7261 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7262 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7263 {
7265  body(re);
7266  vf.join(body._VoxelFunc);
7267  of.join(body._OutsideFunc);
7268 }
7269 
7270 // -----------------------------------------------------------------------------
7271 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7272 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7273 {
7274  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7275  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7276 }
7277 
7278 // -----------------------------------------------------------------------------
7279 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7280 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7281 {
7283  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7284 }
7285 
7286 // -----------------------------------------------------------------------------
7287 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7288 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7289 {
7290  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7291  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
7292 }
7293 
7294 // -----------------------------------------------------------------------------
7295 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7296 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7297 {
7299  body(re);
7300  vf.join(body._VoxelFunc);
7301  of.join(body._OutsideFunc);
7302 }
7303 
7304 // -----------------------------------------------------------------------------
7305 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7306 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7307 {
7308  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7309  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7310 }
7311 
7312 // -----------------------------------------------------------------------------
7313 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7314 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7315 {
7317  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7318 }
7319 
7320 // -----------------------------------------------------------------------------
7321 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7322 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7323 {
7324  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7325  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
7326 }
7327 
7328 //
7329 // Image arguments by reference
7330 //
7331 
7332 // -----------------------------------------------------------------------------
7333 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7334 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
7335 {
7338  body(re);
7339  vf.join(body._VoxelFunc);
7340  of.join(body._OutsideFunc);
7341 }
7342 
7343 // -----------------------------------------------------------------------------
7344 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7345 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7346 {
7347  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7348  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
7349 }
7350 
7351 // -----------------------------------------------------------------------------
7352 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7353 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7354 {
7356  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
7357 }
7358 
7359 // -----------------------------------------------------------------------------
7360 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7361 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7362 {
7363  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7364  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
7365 }
7366 
7367 // -----------------------------------------------------------------------------
7368 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7369 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
7370 {
7371  if (im5.GetTSize()) {
7372  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
7373  } else {
7375  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
7376  body(re);
7377  vf.join(body._VoxelFunc);
7378  of.join(body._OutsideFunc);
7379  }
7380 }
7381 
7382 // -----------------------------------------------------------------------------
7383 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7384 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7385 {
7386  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7387  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
7388 }
7389 
7390 // -----------------------------------------------------------------------------
7391 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7392 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7393 {
7395  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
7396 }
7397 
7398 // -----------------------------------------------------------------------------
7399 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7400 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7401 {
7402  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7403  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
7404 }
7405 
7406 // -----------------------------------------------------------------------------
7407 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7408 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
7409 {
7411  body(attr);
7412  vf.join(body._VoxelFunc);
7413  of.join(body._OutsideFunc);
7414 }
7415 
7416 // -----------------------------------------------------------------------------
7417 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7418 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7419 {
7420  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7421  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
7422 }
7423 
7424 // -----------------------------------------------------------------------------
7425 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7426 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7427 {
7429  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
7430 }
7431 
7432 // -----------------------------------------------------------------------------
7433 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7434 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7435 {
7436  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7437  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
7438 }
7439 
7440 // -----------------------------------------------------------------------------
7441 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7442 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
7443 {
7445  body(re);
7446  vf.join(body._VoxelFunc);
7447  of.join(body._OutsideFunc);
7448 }
7449 
7450 // -----------------------------------------------------------------------------
7451 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7452 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7453 {
7454  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7455  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
7456 }
7457 
7458 // -----------------------------------------------------------------------------
7459 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7460 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
7461 {
7463  body(re);
7464  vf.join(body._VoxelFunc);
7465  of.join(body._OutsideFunc);
7466 }
7467 
7468 // -----------------------------------------------------------------------------
7469 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7470 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7471 {
7472  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7473  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
7474 }
7475 
7476 // -----------------------------------------------------------------------------
7477 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7478 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7479 {
7481  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
7482 }
7483 
7484 // -----------------------------------------------------------------------------
7485 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7486 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7487 {
7488  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7489  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
7490 }
7491 
7492 // -----------------------------------------------------------------------------
7493 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7494 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
7495 {
7497  body(re);
7498  vf.join(body._VoxelFunc);
7499  of.join(body._OutsideFunc);
7500 }
7501 
7502 // -----------------------------------------------------------------------------
7503 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7504 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7505 {
7506  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7507  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
7508 }
7509 
7510 // -----------------------------------------------------------------------------
7511 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7512 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7513 {
7515  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
7516 }
7517 
7518 // -----------------------------------------------------------------------------
7519 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7520 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7521 {
7522  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7523  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
7524 }
7525 
7526 // -----------------------------------------------------------------------------
7527 // ParallelForEachVoxel
7528 // -----------------------------------------------------------------------------
7529 
7530 //
7531 // Image arguments by pointer
7532 //
7533 
7534 // -----------------------------------------------------------------------------
7535 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7536 void ParallelForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7537 {
7538  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7539  blocked_range<int> re(0, im5->GetNumberOfVoxels());
7540  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7541  else parallel_for (re, body);
7542 }
7543 
7544 // -----------------------------------------------------------------------------
7545 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7546 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7547 {
7548  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7549  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
7550 }
7551 
7552 // -----------------------------------------------------------------------------
7553 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7554 void ParallelForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7555 {
7556  if (im5->GetTSize()) {
7557  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
7558  } else {
7559  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7560  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
7561  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7562  else parallel_for (re, body);
7563  }
7564 }
7565 
7566 // -----------------------------------------------------------------------------
7567 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7568 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7569 {
7570  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7571  ParallelForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
7572 }
7573 
7574 // -----------------------------------------------------------------------------
7575 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7576 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7577 {
7578  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7579  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
7580  if (VoxelFunc::IsReduction()) {
7581  if (attr._dt) {
7582  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
7583  } else {
7584  parallel_reduce(re, body);
7585  }
7586  vf.join(body._VoxelFunc);
7587  } else {
7588  if (attr._dt) {
7589  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
7590  } else {
7591  parallel_for(re, body);
7592  }
7593  }
7594 }
7595 
7596 // -----------------------------------------------------------------------------
7597 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7598 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7599 {
7600  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7601  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
7602 }
7603 
7604 // -----------------------------------------------------------------------------
7605 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7606 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7607 {
7608  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7609  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7610  else parallel_for (re, body);
7611 }
7612 
7613 // -----------------------------------------------------------------------------
7614 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7615 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7616 {
7617  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7618  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
7619 }
7620 
7621 // -----------------------------------------------------------------------------
7622 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7623 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7624 {
7625  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7626  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7627  else parallel_for (re, body);
7628 }
7629 
7630 // -----------------------------------------------------------------------------
7631 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7632 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7633 {
7634  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7635  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
7636 }
7637 
7638 // -----------------------------------------------------------------------------
7639 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7640 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7641 {
7642  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
7643  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7644  else parallel_for (re, body);
7645 }
7646 
7647 // -----------------------------------------------------------------------------
7648 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7649 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7650 {
7651  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7652  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
7653 }
7654 
7655 //
7656 // Image arguments by reference
7657 //
7658 
7659 // -----------------------------------------------------------------------------
7660 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7661 void ParallelForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7662 {
7663  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7665  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7666  else parallel_for (re, body);
7667 }
7668 
7669 // -----------------------------------------------------------------------------
7670 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7671 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7672 {
7673  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7674  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
7675 }
7676 
7677 // -----------------------------------------------------------------------------
7678 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7679 void ParallelForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7680 {
7681  if (im5.GetTSize()) {
7682  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
7683  } else {
7684  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7685  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
7686  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7687  else parallel_for (re, body);
7688  }
7689 }
7690 
7691 // -----------------------------------------------------------------------------
7692 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7693 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7694 {
7695  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7696  ParallelForEachVoxel(im1, im2, im3, im4, im5, vf);
7697 }
7698 
7699 // -----------------------------------------------------------------------------
7700 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7701 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7702 {
7703  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7704  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
7705  if (VoxelFunc::IsReduction()) {
7706  if (attr._dt) {
7707  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
7708  } else {
7709  parallel_reduce(re, body);
7710  }
7711  vf.join(body._VoxelFunc);
7712  } else {
7713  if (attr._dt) {
7714  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
7715  } else {
7716  parallel_for(re, body);
7717  }
7718  }
7719 }
7720 
7721 // -----------------------------------------------------------------------------
7722 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7723 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7724 {
7725  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7726  ParallelForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
7727 }
7728 
7729 // -----------------------------------------------------------------------------
7730 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7731 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7732 {
7733  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7734  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7735  else parallel_for (re, body);
7736 }
7737 
7738 // -----------------------------------------------------------------------------
7739 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7740 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7741 {
7742  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7743  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
7744 }
7745 
7746 // -----------------------------------------------------------------------------
7747 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7748 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7749 {
7750  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7751  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7752  else parallel_for (re, body);
7753 }
7754 
7755 // -----------------------------------------------------------------------------
7756 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7757 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7758 {
7759  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7760  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
7761 }
7762 
7763 // -----------------------------------------------------------------------------
7764 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7765 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
7766 {
7767  QuinaryForEachVoxelBody_1Const<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
7768  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
7769  else parallel_for (re, body);
7770 }
7771 
7772 // -----------------------------------------------------------------------------
7773 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7774 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
7775 {
7776  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7777  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
7778 }
7779 
7780 // -----------------------------------------------------------------------------
7781 // ParallelForEachVoxelIf
7782 // -----------------------------------------------------------------------------
7783 
7784 //
7785 // Image arguments by pointer
7786 //
7787 
7788 // -----------------------------------------------------------------------------
7789 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7790 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7791 {
7793  blocked_range<int> re(0, im5->GetNumberOfVoxels());
7794  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7795  parallel_reduce(re, body);
7796  vf.join(body._VoxelFunc);
7797  of.join(body._OutsideFunc);
7798  } else {
7799  parallel_for(re, body);
7800  }
7801 }
7802 
7803 // -----------------------------------------------------------------------------
7804 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7805 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7806 {
7807  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7808  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7809 }
7810 
7811 // -----------------------------------------------------------------------------
7812 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7813 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7814 {
7816  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7817 }
7818 
7819 // -----------------------------------------------------------------------------
7820 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7821 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7822 {
7823  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7824  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
7825 }
7826 
7827 // -----------------------------------------------------------------------------
7828 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7829 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7830 {
7831  if (im5->GetTSize()) {
7832  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7833  } else {
7835  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
7836  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7837  parallel_reduce(re, body);
7838  vf.join(body._VoxelFunc);
7839  of.join(body._OutsideFunc);
7840  } else {
7841  parallel_for(re, body);
7842  }
7843  }
7844 }
7845 
7846 // -----------------------------------------------------------------------------
7847 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7848 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7849 {
7850  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7851  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7852 }
7853 
7854 // -----------------------------------------------------------------------------
7855 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7856 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7857 {
7859  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
7860 }
7861 
7862 // -----------------------------------------------------------------------------
7863 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7864 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7865 {
7866  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7867  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
7868 }
7869 
7870 // -----------------------------------------------------------------------------
7871 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7872 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7873 {
7875  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
7876  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7877  if (attr._dt) {
7878  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
7879  } else {
7880  parallel_reduce(re, body);
7881  }
7882  vf.join(body._VoxelFunc);
7883  of.join(body._OutsideFunc);
7884  } else {
7885  if (attr._dt) {
7886  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
7887  } else {
7888  parallel_for(re, body);
7889  }
7890  }
7891 }
7892 
7893 // -----------------------------------------------------------------------------
7894 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7895 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7896 {
7897  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7898  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
7899 }
7900 
7901 // -----------------------------------------------------------------------------
7902 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7903 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7904 {
7906  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
7907 }
7908 
7909 // -----------------------------------------------------------------------------
7910 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7911 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7912 {
7913  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7914  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
7915 }
7916 
7917 // -----------------------------------------------------------------------------
7918 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7919 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7920 {
7922  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7923  parallel_reduce(re, body);
7924  vf.join(body._VoxelFunc);
7925  of.join(body._OutsideFunc);
7926  } else {
7927  parallel_for(re, body);
7928  }
7929 }
7930 
7931 // -----------------------------------------------------------------------------
7932 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7933 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7934 {
7935  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7936  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7937 }
7938 
7939 // -----------------------------------------------------------------------------
7940 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7941 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7942 {
7944  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7945 }
7946 
7947 // -----------------------------------------------------------------------------
7948 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7949 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7950 {
7951  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7952  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
7953 }
7954 
7955 // -----------------------------------------------------------------------------
7956 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7957 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7958 {
7960  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7961  parallel_reduce(re, body);
7962  vf.join(body._VoxelFunc);
7963  of.join(body._OutsideFunc);
7964  } else {
7965  parallel_for(re, body);
7966  }
7967 }
7968 
7969 // -----------------------------------------------------------------------------
7970 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7971 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7972 {
7973  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7974  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7975 }
7976 
7977 // -----------------------------------------------------------------------------
7978 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7979 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
7980 {
7982  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
7983 }
7984 
7985 // -----------------------------------------------------------------------------
7986 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
7987 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
7988 {
7989  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
7990  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
7991 }
7992 
7993 // -----------------------------------------------------------------------------
7994 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
7995 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
7996 {
7998  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
7999  parallel_reduce(re, body);
8000  vf.join(body._VoxelFunc);
8001  of.join(body._OutsideFunc);
8002  } else {
8003  parallel_for(re, body);
8004  }
8005 }
8006 
8007 // -----------------------------------------------------------------------------
8008 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8009 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8010 {
8011  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8012  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
8013 }
8014 
8015 // -----------------------------------------------------------------------------
8016 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8017 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8018 {
8020  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
8021 }
8022 
8023 // -----------------------------------------------------------------------------
8024 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8025 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8026 {
8027  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8028  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
8029 }
8030 
8031 //
8032 // Image arguments by reference
8033 //
8034 
8035 // -----------------------------------------------------------------------------
8036 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8037 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8038 {
8041  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8042  parallel_reduce(re, body);
8043  vf.join(body._VoxelFunc);
8044  of.join(body._OutsideFunc);
8045  } else {
8046  parallel_for(re, body);
8047  }
8048 }
8049 
8050 // -----------------------------------------------------------------------------
8051 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8052 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8053 {
8054  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8055  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
8056 }
8057 
8058 // -----------------------------------------------------------------------------
8059 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8060 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8061 {
8063  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
8064 }
8065 
8066 // -----------------------------------------------------------------------------
8067 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8068 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8069 {
8070  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8071  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
8072 }
8073 
8074 // -----------------------------------------------------------------------------
8075 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8076 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8077 {
8078  if (im5.GetTSize()) {
8079  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
8080  } else {
8082  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
8083  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8084  parallel_reduce(re, body);
8085  vf.join(body._VoxelFunc);
8086  of.join(body._OutsideFunc);
8087  } else {
8088  parallel_for(re, body);
8089  }
8090  }
8091 }
8092 
8093 // -----------------------------------------------------------------------------
8094 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8095 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8096 {
8097  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8098  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
8099 }
8100 
8101 // -----------------------------------------------------------------------------
8102 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8103 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8104 {
8106  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
8107 }
8108 
8109 // -----------------------------------------------------------------------------
8110 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8111 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8112 {
8113  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8114  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
8115 }
8116 
8117 // -----------------------------------------------------------------------------
8118 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8119 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8120 {
8122  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
8123  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8124  if (attr._dt) {
8125  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
8126  } else {
8127  parallel_reduce(re, body);
8128  }
8129  vf.join(body._VoxelFunc);
8130  of.join(body._OutsideFunc);
8131  } else {
8132  if (attr._dt) {
8133  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
8134  } else {
8135  parallel_for(re, body);
8136  }
8137  }
8138 }
8139 
8140 // -----------------------------------------------------------------------------
8141 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8142 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8143 {
8144  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8145  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
8146 }
8147 
8148 // -----------------------------------------------------------------------------
8149 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8150 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8151 {
8153  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
8154 }
8155 
8156 // -----------------------------------------------------------------------------
8157 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8158 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8159 {
8160  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8161  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
8162 }
8163 
8164 // -----------------------------------------------------------------------------
8165 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8166 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8167 {
8169  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8170  parallel_reduce(re, body);
8171  vf.join(body._VoxelFunc);
8172  of.join(body._OutsideFunc);
8173  } else {
8174  parallel_for(re, body);
8175  }
8176 }
8177 
8178 // -----------------------------------------------------------------------------
8179 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8180 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8181 {
8182  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8183  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
8184 }
8185 
8186 // -----------------------------------------------------------------------------
8187 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8188 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8189 {
8191  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
8192 }
8193 
8194 // -----------------------------------------------------------------------------
8195 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8196 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8197 {
8198  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8199  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
8200 }
8201 
8202 // -----------------------------------------------------------------------------
8203 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8204 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8205 {
8207  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8208  parallel_reduce(re, body);
8209  vf.join(body._VoxelFunc);
8210  of.join(body._OutsideFunc);
8211  } else {
8212  parallel_for(re, body);
8213  }
8214 }
8215 
8216 // -----------------------------------------------------------------------------
8217 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8218 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8219 {
8220  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8221  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
8222 }
8223 
8224 // -----------------------------------------------------------------------------
8225 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8226 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8227 {
8229  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
8230 }
8231 
8232 // -----------------------------------------------------------------------------
8233 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8234 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8235 {
8236  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8237  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
8238 }
8239 
8240 // -----------------------------------------------------------------------------
8241 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8242 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8243 {
8245  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
8246  parallel_reduce(re, body);
8247  vf.join(body._VoxelFunc);
8248  of.join(body._OutsideFunc);
8249  } else {
8250  parallel_for(re, body);
8251  }
8252 }
8253 
8254 // -----------------------------------------------------------------------------
8255 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8256 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8257 {
8258  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8259  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
8260 }
8261 
8262 // -----------------------------------------------------------------------------
8263 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8264 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8265 {
8267  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
8268 }
8269 
8270 // -----------------------------------------------------------------------------
8271 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8272 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8273 {
8274  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8275  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
8276 }
8277 
8278 // =============================================================================
8279 // 5 non-const images
8280 // =============================================================================
8281 
8282 // -----------------------------------------------------------------------------
8283 /**
8284  * ForEachVoxel body for voxel function of 5 non-const images
8285  */
8286 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8287 struct QuinaryForEachVoxelBody : public ForEachVoxelBody<VoxelFunc>
8288 {
8289  GenericImage<T1> &im1;
8290  GenericImage<T2> &im2;
8291  GenericImage<T3> &im3;
8292  GenericImage<T4> &im4;
8293  GenericImage<T5> &im5;
8294 
8295  /// Constructor
8297  GenericImage<T2> &im2,
8298  GenericImage<T3> &im3,
8299  GenericImage<T4> &im4,
8300  GenericImage<T5> &im5,
8301  VoxelFunc &vf)
8302  :
8303  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
8304  {}
8305 
8306  /// Copy constructor
8308  :
8309  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
8310  {}
8311 
8312  /// Split constructor
8314  :
8315  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
8316  {}
8317 
8318  /// Process entire image
8319  void operator ()(const ImageAttributes &attr) const
8320  {
8321  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
8322  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
8323  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
8324  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
8325  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
8326 
8327  const int T = (attr._dt ? attr._t : 1);
8328 
8329  for (int l = 0; l < T; ++l)
8330  for (int k = 0; k < attr._z; ++k)
8331  for (int j = 0; j < attr._y; ++j)
8332  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
8333  // const_cast such that voxel functions need only implement
8334  // non-const operator() which is required for parallel_reduce
8335  const_cast<QuinaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3, p4, p5);
8336  }
8337  }
8338 
8339  /// Process image region using linear index
8340  void operator ()(const blocked_range<int> &re) const
8341  {
8342  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
8343  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
8344  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
8345  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
8346  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
8347 
8348  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
8349  // const_cast such that voxel functions need only implement
8350  // non-const operator() which is required for parallel_reduce
8351  const_cast<QuinaryForEachVoxelBody *>(this)->_VoxelFunc(im5, idx, p1, p2, p3, p4, p5);
8352  }
8353  }
8354 
8355  /// Process 2D image region
8356  void operator ()(const blocked_range2d<int> &re) const
8357  {
8358  const int bi = re.cols().begin();
8359  const int bj = re.rows().begin();
8360  const int ei = re.cols().end();
8361  const int ej = re.rows().end();
8362 
8363  const int s1 = im5.GetX() - (ei - bi);
8364 
8365  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8366  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8367  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8368  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8369  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8370 
8371  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
8372  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
8373  // const_cast such that voxel functions need only implement
8374  // non-const operator() which is required for parallel_reduce
8375  const_cast<QuinaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
8376  }
8377  }
8378 
8379  /// Process 3D image region
8380  void operator ()(const blocked_range3d<int> &re) const
8381  {
8382  const int bi = re.cols ().begin();
8383  const int bj = re.rows ().begin();
8384  const int bk = re.pages().begin();
8385  const int ei = re.cols ().end();
8386  const int ej = re.rows ().end();
8387  const int ek = re.pages().end();
8388 
8389  const int s1 = im5.GetX() - (ei - bi);
8390  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
8391 
8392  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
8393  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
8394  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
8395  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
8396  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
8397 
8398  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
8399  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
8400  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
8401  // const_cast such that voxel functions need only implement
8402  // non-const operator() which is required for parallel_reduce
8403  const_cast<QuinaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
8404  }
8405  }
8406 };
8407 
8408 // -----------------------------------------------------------------------------
8409 /**
8410  * ForEachVoxel body for inside and outside unary voxel function of 5 non-const images
8411  */
8412 template <class T1, class T2, class T3, class T4, class T5,
8413  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
8414  class Domain = ForEachVoxelDomain::Foreground>
8415 struct QuinaryForEachVoxelIfBody : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
8416 {
8417  GenericImage<T1> &im1;
8418  GenericImage<T2> &im2;
8419  GenericImage<T3> &im3;
8420  GenericImage<T4> &im4;
8421  GenericImage<T5> &im5;
8422 
8423  /// Constructor
8425  GenericImage<T2> &im2,
8426  GenericImage<T3> &im3,
8427  GenericImage<T4> &im4,
8428  GenericImage<T5> &im5,
8429  VoxelFunc &vf, OutsideFunc &of)
8430  :
8431  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3), im4(im4), im5(im5)
8432  {}
8433 
8434  /// Copy constructor
8436  :
8437  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
8438  {}
8439 
8440  /// Split constructor
8442  :
8443  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3), im4(o.im4), im5(o.im5)
8444  {}
8445 
8446  /// Process entire image
8447  void operator ()(const ImageAttributes &attr) const
8448  {
8449  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
8450  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
8451  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
8452  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels();
8453  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels();
8454 
8455  const int T = (attr._dt ? attr._t : 1);
8456 
8457  for (int l = 0; l < T; ++l)
8458  for (int k = 0; k < attr._z; ++k)
8459  for (int j = 0; j < attr._y; ++j)
8460  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3, ++p4, ++p5) {
8461  if (Domain::IsInside(im5, i, j, k, l, p5)) {
8462  // const_cast such that voxel functions need only implement
8463  // non-const operator() which is required for parallel_reduce
8464  const_cast<QuinaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3, p4, p5);
8465  } else const_cast<QuinaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3, p4, p5);
8466  }
8467  }
8468 
8469  /// Process image region using linear index
8470  void operator ()(const blocked_range<int> &re) const
8471  {
8472  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
8473  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
8474  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
8475  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels() + re.begin();
8476  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels() + re.begin();
8477 
8478  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
8479  if (Domain::IsInside(im5, idx, p5)) {
8480  // const_cast such that voxel functions need only implement
8481  // non-const operator() which is required for parallel_reduce
8482  const_cast<QuinaryForEachVoxelIfBody *>(this)->_VoxelFunc (im5, idx, p1, p2, p3, p4, p5);
8483  } else const_cast<QuinaryForEachVoxelIfBody *>(this)->_OutsideFunc(im5, idx, p1, p2, p3, p4, p5);
8484  }
8485  }
8486 
8487  /// Process 2D image region
8488  void operator ()(const blocked_range2d<int> &re) const
8489  {
8490  const int bi = re.cols().begin();
8491  const int bj = re.rows().begin();
8492  const int ei = re.cols().end();
8493  const int ej = re.rows().end();
8494 
8495  const int s1 = im5.GetX() - (ei - bi);
8496 
8497  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8498  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8499  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8500  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8501  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, this->_k, this->_l);
8502 
8503  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
8504  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
8505  if (Domain::IsInside(im5, i, j, this->_k, this->_l, p5)) {
8506  // const_cast such that voxel functions need only implement
8507  // non-const operator() which is required for parallel_reduce
8508  const_cast<QuinaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
8509  } else const_cast<QuinaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3, p4, p5);
8510  }
8511  }
8512 
8513  /// Process 3D image region
8514  void operator ()(const blocked_range3d<int> &re) const
8515  {
8516  const int bi = re.cols ().begin();
8517  const int bj = re.rows ().begin();
8518  const int bk = re.pages().begin();
8519  const int ei = re.cols ().end();
8520  const int ej = re.rows ().end();
8521  const int ek = re.pages().end();
8522 
8523  const int s1 = im5.GetX() - (ei - bi);
8524  const int s2 = (im5.GetY() - (ej - bj)) * im5.GetX();
8525 
8526  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
8527  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
8528  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
8529  T4 *p4 = im4.IsEmpty() ? NULL : im4.GetPointerToVoxels(bi, bj, bk, this->_l);
8530  T5 *p5 = im5.IsEmpty() ? NULL : im5.GetPointerToVoxels(bi, bj, bk, this->_l);
8531 
8532  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2, p4 += s2, p5 += s2)
8533  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1, p4 += s1, p5 += s1)
8534  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1, p4 += 1, p5 += 1) {
8535  if (Domain::IsInside(im5, i, j, k, this->_l, p5)) {
8536  // const_cast such that voxel functions need only implement
8537  // non-const operator() which is required for parallel_reduce
8538  const_cast<QuinaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3, p4, p5);
8539  } else const_cast<QuinaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3, p4, p5);
8540  }
8541  }
8542 };
8543 
8544 // -----------------------------------------------------------------------------
8545 // ForEachVoxel
8546 // -----------------------------------------------------------------------------
8547 
8548 //
8549 // Image arguments by pointer
8550 //
8551 
8552 // -----------------------------------------------------------------------------
8553 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8554 void ForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8555 {
8556  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
8557  blocked_range<int> re(0, im5->GetNumberOfVoxels());
8558  body(re);
8559  vf.join(body._VoxelFunc);
8560 }
8561 
8562 // -----------------------------------------------------------------------------
8563 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8564 void ForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8565 {
8566  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8567  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
8568 }
8569 
8570 // -----------------------------------------------------------------------------
8571 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8572 void ForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8573 {
8574  if (im5->GetTSize()) {
8575  ForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
8576  } else {
8577  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
8578  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
8579  body(re);
8580  vf.join(body._VoxelFunc);
8581  }
8582 }
8583 
8584 // -----------------------------------------------------------------------------
8585 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8586 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8587 {
8588  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8589  ForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
8590 }
8591 
8592 // -----------------------------------------------------------------------------
8593 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8594 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8595 {
8596  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
8597  body(attr);
8598  vf.join(body._VoxelFunc);
8599 }
8600 
8601 // -----------------------------------------------------------------------------
8602 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8603 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8604 {
8605  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8606  ForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
8607 }
8608 
8609 // -----------------------------------------------------------------------------
8610 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8611 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8612 {
8613  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
8614  body(re);
8615  vf.join(body._VoxelFunc);
8616 }
8617 
8618 // -----------------------------------------------------------------------------
8619 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8620 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8621 {
8622  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8623  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
8624 }
8625 
8626 // -----------------------------------------------------------------------------
8627 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8628 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8629 {
8630  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
8631  body(re);
8632  vf.join(body._VoxelFunc);
8633 }
8634 
8635 // -----------------------------------------------------------------------------
8636 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8637 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8638 {
8639  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8640  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
8641 }
8642 
8643 // -----------------------------------------------------------------------------
8644 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8645 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8646 {
8647  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
8648  body(re);
8649  vf.join(body._VoxelFunc);
8650 }
8651 
8652 // -----------------------------------------------------------------------------
8653 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8654 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8655 {
8656  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8657  ForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
8658 }
8659 
8660 //
8661 // Image arguments by reference
8662 //
8663 
8664 // -----------------------------------------------------------------------------
8665 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8666 void ForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8667 {
8668  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
8670  body(re);
8671  vf.join(body._VoxelFunc);
8672 }
8673 
8674 // -----------------------------------------------------------------------------
8675 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8676 void ForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8677 {
8678  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8679  ForEachScalar(im1, im2, im3, im4, im5, vf);
8680 }
8681 
8682 // -----------------------------------------------------------------------------
8683 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8684 void ForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8685 {
8686  if (im5.GetTSize()) {
8687  ForEachScalar(im1, im2, im3, im4, im5, vf);
8688  } else {
8689  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
8690  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
8691  body(re);
8692  vf.join(body._VoxelFunc);
8693  }
8694 }
8695 
8696 // -----------------------------------------------------------------------------
8697 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8698 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8699 {
8700  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8701  ForEachVoxel(im1, im2, im3, im4, im5, vf);
8702 }
8703 
8704 // -----------------------------------------------------------------------------
8705 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8706 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8707 {
8708  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
8709  body(attr);
8710  vf.join(body._VoxelFunc);
8711 }
8712 
8713 // -----------------------------------------------------------------------------
8714 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8715 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8716 {
8717  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8718  ForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
8719 }
8720 
8721 // -----------------------------------------------------------------------------
8722 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8723 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8724 {
8725  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
8726  body(re);
8727  vf.join(body._VoxelFunc);
8728 }
8729 
8730 // -----------------------------------------------------------------------------
8731 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8732 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8733 {
8734  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8735  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
8736 }
8737 
8738 // -----------------------------------------------------------------------------
8739 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8740 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8741 {
8742  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
8743  body(re);
8744  vf.join(body._VoxelFunc);
8745 }
8746 
8747 // -----------------------------------------------------------------------------
8748 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8749 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8750 {
8751  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8752  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
8753 }
8754 
8755 // -----------------------------------------------------------------------------
8756 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8757 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
8758 {
8759  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
8760  body(re);
8761  vf.join(body._VoxelFunc);
8762 }
8763 
8764 // -----------------------------------------------------------------------------
8765 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8766 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8767 {
8768  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8769  ForEachVoxel(re, im1, im2, im3, im4, im5, vf);
8770 }
8771 
8772 // -----------------------------------------------------------------------------
8773 // ForEachVoxelIf
8774 // -----------------------------------------------------------------------------
8775 
8776 //
8777 // Image arguments by pointer
8778 //
8779 
8780 // -----------------------------------------------------------------------------
8781 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8782 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
8783 {
8784  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
8785  blocked_range<int> re(0, im5->GetNumberOfVoxels());
8786  body(re);
8787  vf.join(body._VoxelFunc);
8788  of.join(body._OutsideFunc);
8789 }
8790 
8791 // -----------------------------------------------------------------------------
8792 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8793 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8794 {
8795  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8796  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
8797 }
8798 
8799 // -----------------------------------------------------------------------------
8800 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8801 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8802 {
8804  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
8805 }
8806 
8807 // -----------------------------------------------------------------------------
8808 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8809 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8810 {
8811  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8812  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
8813 }
8814 
8815 // -----------------------------------------------------------------------------
8816 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8817 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
8818 {
8819  if (im5->GetTSize()) {
8820  ForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
8821  } else {
8822  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
8823  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
8824  body(re);
8825  vf.join(body._VoxelFunc);
8826  of.join(body._OutsideFunc);
8827  }
8828 }
8829 
8830 // -----------------------------------------------------------------------------
8831 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8832 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8833 {
8834  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8835  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
8836 }
8837 
8838 // -----------------------------------------------------------------------------
8839 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8840 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8841 {
8843  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
8844 }
8845 
8846 // -----------------------------------------------------------------------------
8847 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8848 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8849 {
8850  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8851  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
8852 }
8853 
8854 // -----------------------------------------------------------------------------
8855 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8856 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
8857 {
8858  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
8859  body(attr);
8860  vf.join(body._VoxelFunc);
8861  of.join(body._OutsideFunc);
8862 }
8863 
8864 // -----------------------------------------------------------------------------
8865 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8866 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8867 {
8868  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8869  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
8870 }
8871 
8872 // -----------------------------------------------------------------------------
8873 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8874 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8875 {
8877  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
8878 }
8879 
8880 // -----------------------------------------------------------------------------
8881 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8882 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8883 {
8884  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8885  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
8886 }
8887 
8888 // -----------------------------------------------------------------------------
8889 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8890 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
8891 {
8892  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
8893  body(re);
8894  vf.join(body._VoxelFunc);
8895  of.join(body._OutsideFunc);
8896 }
8897 
8898 // -----------------------------------------------------------------------------
8899 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8900 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8901 {
8902  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8903  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
8904 }
8905 
8906 // -----------------------------------------------------------------------------
8907 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8908 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
8909 {
8910  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
8911  body(re);
8912  vf.join(body._VoxelFunc);
8913  of.join(body._OutsideFunc);
8914 }
8915 
8916 // -----------------------------------------------------------------------------
8917 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8918 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8919 {
8920  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8921  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
8922 }
8923 
8924 // -----------------------------------------------------------------------------
8925 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8926 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8927 {
8929  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
8930 }
8931 
8932 // -----------------------------------------------------------------------------
8933 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8934 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8935 {
8936  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8937  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
8938 }
8939 
8940 // -----------------------------------------------------------------------------
8941 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8942 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
8943 {
8944  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
8945  body(re);
8946  vf.join(body._VoxelFunc);
8947  of.join(body._OutsideFunc);
8948 }
8949 
8950 // -----------------------------------------------------------------------------
8951 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8952 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8953 {
8954  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8955  ForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
8956 }
8957 
8958 // -----------------------------------------------------------------------------
8959 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8960 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
8961 {
8963  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
8964 }
8965 
8966 // -----------------------------------------------------------------------------
8967 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8968 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
8969 {
8970  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8971  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
8972 }
8973 
8974 //
8975 // Image arguments by reference
8976 //
8977 
8978 // -----------------------------------------------------------------------------
8979 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8980 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
8981 {
8984  body(re);
8985  vf.join(body._VoxelFunc);
8986  of.join(body._OutsideFunc);
8987 }
8988 
8989 // -----------------------------------------------------------------------------
8990 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
8991 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
8992 {
8993  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
8994  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
8995 }
8996 
8997 // -----------------------------------------------------------------------------
8998 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
8999 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9000 {
9002  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9003 }
9004 
9005 // -----------------------------------------------------------------------------
9006 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9007 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9008 {
9009  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9010  ForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
9011 }
9012 
9013 // -----------------------------------------------------------------------------
9014 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9015 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9016 {
9017  if (im5.GetTSize()) {
9018  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9019  } else {
9021  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
9022  body(re);
9023  vf.join(body._VoxelFunc);
9024  of.join(body._OutsideFunc);
9025  }
9026 }
9027 
9028 // -----------------------------------------------------------------------------
9029 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9030 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9031 {
9032  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9033  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9034 }
9035 
9036 // -----------------------------------------------------------------------------
9037 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9038 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9039 {
9041  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9042 }
9043 
9044 // -----------------------------------------------------------------------------
9045 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9046 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9047 {
9048  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9049  ForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
9050 }
9051 
9052 // -----------------------------------------------------------------------------
9053 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9054 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9055 {
9057  body(attr);
9058  vf.join(body._VoxelFunc);
9059  of.join(body._OutsideFunc);
9060 }
9061 
9062 // -----------------------------------------------------------------------------
9063 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9064 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9065 {
9066  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9067  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
9068 }
9069 
9070 // -----------------------------------------------------------------------------
9071 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9072 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9073 {
9075  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
9076 }
9077 
9078 // -----------------------------------------------------------------------------
9079 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9080 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9081 {
9082  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9083  ForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
9084 }
9085 
9086 // -----------------------------------------------------------------------------
9087 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9088 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9089 {
9091  body(re);
9092  vf.join(body._VoxelFunc);
9093  of.join(body._OutsideFunc);
9094 }
9095 
9096 // -----------------------------------------------------------------------------
9097 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9098 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9099 {
9100  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9101  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9102 }
9103 
9104 // -----------------------------------------------------------------------------
9105 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9106 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9107 {
9109  body(re);
9110  vf.join(body._VoxelFunc);
9111  of.join(body._OutsideFunc);
9112 }
9113 
9114 // -----------------------------------------------------------------------------
9115 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9116 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9117 {
9118  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9119  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9120 }
9121 
9122 // -----------------------------------------------------------------------------
9123 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9124 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9125 {
9127  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9128 }
9129 
9130 // -----------------------------------------------------------------------------
9131 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9132 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9133 {
9134  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9135  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
9136 }
9137 
9138 // -----------------------------------------------------------------------------
9139 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9140 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9141 {
9143  body(re);
9144  vf.join(body._VoxelFunc);
9145  of.join(body._OutsideFunc);
9146 }
9147 
9148 // -----------------------------------------------------------------------------
9149 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9150 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9151 {
9152  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9153  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9154 }
9155 
9156 // -----------------------------------------------------------------------------
9157 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9158 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9159 {
9161  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9162 }
9163 
9164 // -----------------------------------------------------------------------------
9165 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9166 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9167 {
9168  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9169  ForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
9170 }
9171 
9172 // -----------------------------------------------------------------------------
9173 // ParallelForEachVoxel
9174 // -----------------------------------------------------------------------------
9175 
9176 //
9177 // Image arguments by pointer
9178 //
9179 
9180 // -----------------------------------------------------------------------------
9181 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9182 void ParallelForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9183 {
9184  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
9185  blocked_range<int> re(0, im5->GetNumberOfVoxels());
9186  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9187  else parallel_for (re, body);
9188 }
9189 
9190 // -----------------------------------------------------------------------------
9191 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9192 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9193 {
9194  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9195  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
9196 }
9197 
9198 // -----------------------------------------------------------------------------
9199 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9200 void ParallelForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9201 {
9202  if (im5->GetTSize()) {
9203  ParallelForEachScalar(*im1, *im2, *im3, *im4, *im5, vf);
9204  } else {
9205  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
9206  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
9207  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9208  else parallel_for (re, body);
9209  }
9210 }
9211 
9212 // -----------------------------------------------------------------------------
9213 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9214 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9215 {
9216  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9217  ParallelForEachVoxel(*im1, *im2, *im3, *im4, *im5, vf);
9218 }
9219 
9220 // -----------------------------------------------------------------------------
9221 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9222 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9223 {
9224  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
9225  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
9226  if (VoxelFunc::IsReduction()) {
9227  if (attr._dt) {
9228  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
9229  } else {
9230  parallel_reduce(re, body);
9231  }
9232  vf.join(body._VoxelFunc);
9233  } else {
9234  if (attr._dt) {
9235  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
9236  } else {
9237  parallel_for(re, body);
9238  }
9239  }
9240 }
9241 
9242 // -----------------------------------------------------------------------------
9243 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9244 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9245 {
9246  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9247  ParallelForEachVoxel(attr, *im1, *im2, *im3, *im4, *im5, vf);
9248 }
9249 
9250 // -----------------------------------------------------------------------------
9251 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9252 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9253 {
9254  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
9255  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9256  else parallel_for (re, body);
9257 }
9258 
9259 // -----------------------------------------------------------------------------
9260 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9261 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9262 {
9263  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9264  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
9265 }
9266 
9267 // -----------------------------------------------------------------------------
9268 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9269 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9270 {
9271  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
9272  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9273  else parallel_for (re, body);
9274 }
9275 
9276 // -----------------------------------------------------------------------------
9277 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9278 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9279 {
9280  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9281  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
9282 }
9283 
9284 // -----------------------------------------------------------------------------
9285 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9286 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9287 {
9288  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(*im1, *im2, *im3, *im4, *im5, vf);
9289  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9290  else parallel_for (re, body);
9291 }
9292 
9293 // -----------------------------------------------------------------------------
9294 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9295 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9296 {
9297  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9298  ParallelForEachVoxel(re, *im1, *im2, *im3, *im4, *im5, vf);
9299 }
9300 
9301 //
9302 // Image arguments by reference
9303 //
9304 
9305 // -----------------------------------------------------------------------------
9306 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9307 void ParallelForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9308 {
9309  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
9311  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9312  else parallel_for (re, body);
9313 }
9314 
9315 // -----------------------------------------------------------------------------
9316 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9317 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9318 {
9319  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9320  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
9321 }
9322 
9323 // -----------------------------------------------------------------------------
9324 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9325 void ParallelForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9326 {
9327  if (im5.GetTSize()) {
9328  ParallelForEachScalar(im1, im2, im3, im4, im5, vf);
9329  } else {
9330  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
9331  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
9332  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9333  else parallel_for (re, body);
9334  }
9335 }
9336 
9337 // -----------------------------------------------------------------------------
9338 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9339 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9340 {
9341  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9342  ParallelForEachVoxel(im1, im2, im3, im4, im5, vf);
9343 }
9344 
9345 // -----------------------------------------------------------------------------
9346 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9347 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9348 {
9349  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
9350  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
9351  if (VoxelFunc::IsReduction()) {
9352  if (attr._dt) {
9353  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
9354  } else {
9355  parallel_reduce(re, body);
9356  }
9357  vf.join(body._VoxelFunc);
9358  } else {
9359  if (attr._dt) {
9360  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
9361  } else {
9362  parallel_for(re, body);
9363  }
9364  }
9365 }
9366 
9367 // -----------------------------------------------------------------------------
9368 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9369 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9370 {
9371  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9372  ParallelForEachVoxel(attr, im1, im2, im3, im4, im5, vf);
9373 }
9374 
9375 // -----------------------------------------------------------------------------
9376 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9377 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9378 {
9379  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
9380  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9381  else parallel_for (re, body);
9382 }
9383 
9384 // -----------------------------------------------------------------------------
9385 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9386 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9387 {
9388  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9389  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
9390 }
9391 
9392 // -----------------------------------------------------------------------------
9393 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9394 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9395 {
9396  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
9397  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9398  else parallel_for (re, body);
9399 }
9400 
9401 // -----------------------------------------------------------------------------
9402 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9403 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9404 {
9405  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9406  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
9407 }
9408 
9409 // -----------------------------------------------------------------------------
9410 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9411 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9412 {
9413  QuinaryForEachVoxelBody<T1, T2, T3, T4, T5, VoxelFunc> body(im1, im2, im3, im4, im5, vf);
9414  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
9415  else parallel_for (re, body);
9416 }
9417 
9418 // -----------------------------------------------------------------------------
9419 template <class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9420 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9421 {
9422  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9423  ParallelForEachVoxel(re, im1, im2, im3, im4, im5, vf);
9424 }
9425 
9426 // -----------------------------------------------------------------------------
9427 // ParallelForEachVoxelIf
9428 // -----------------------------------------------------------------------------
9429 
9430 //
9431 // Image arguments by pointer
9432 //
9433 
9434 // -----------------------------------------------------------------------------
9435 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9436 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
9437 {
9438  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
9439  blocked_range<int> re(0, im5->GetNumberOfVoxels());
9440  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9441  parallel_reduce(re, body);
9442  vf.join(body._VoxelFunc);
9443  of.join(body._OutsideFunc);
9444  } else {
9445  parallel_for(re, body);
9446  }
9447 }
9448 
9449 // -----------------------------------------------------------------------------
9450 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9451 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9452 {
9453  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9454  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
9455 }
9456 
9457 // -----------------------------------------------------------------------------
9458 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9459 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9460 {
9462  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
9463 }
9464 
9465 // -----------------------------------------------------------------------------
9466 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9467 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9468 {
9469  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9470  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
9471 }
9472 
9473 // -----------------------------------------------------------------------------
9474 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9475 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
9476 {
9477  if (im5->GetTSize()) {
9478  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
9479  } else {
9480  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
9481  blocked_range<int> re(0, im5->GetNumberOfVoxels() / im5->GetT());
9482  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9483  parallel_reduce(re, body);
9484  vf.join(body._VoxelFunc);
9485  of.join(body._OutsideFunc);
9486  } else {
9487  parallel_for(re, body);
9488  }
9489  }
9490 }
9491 
9492 // -----------------------------------------------------------------------------
9493 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9494 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9495 {
9496  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9497  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
9498 }
9499 
9500 // -----------------------------------------------------------------------------
9501 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9502 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9503 {
9505  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf, of);
9506 }
9507 
9508 // -----------------------------------------------------------------------------
9509 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9510 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9511 {
9512  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9513  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, *im4, *im5, vf);
9514 }
9515 
9516 // -----------------------------------------------------------------------------
9517 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9518 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
9519 {
9520  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
9521  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
9522  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9523  if (attr._dt) {
9524  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
9525  } else {
9526  parallel_reduce(re, body);
9527  }
9528  vf.join(body._VoxelFunc);
9529  of.join(body._OutsideFunc);
9530  } else {
9531  if (attr._dt) {
9532  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
9533  } else {
9534  parallel_for(re, body);
9535  }
9536  }
9537 }
9538 
9539 // -----------------------------------------------------------------------------
9540 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9541 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9542 {
9543  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9544  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
9545 }
9546 
9547 // -----------------------------------------------------------------------------
9548 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9549 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9550 {
9552  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf, of);
9553 }
9554 
9555 // -----------------------------------------------------------------------------
9556 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9557 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9558 {
9559  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9560  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, *im4, *im5, vf);
9561 }
9562 
9563 // -----------------------------------------------------------------------------
9564 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9565 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
9566 {
9567  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
9568  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9569  parallel_reduce(re, body);
9570  vf.join(body._VoxelFunc);
9571  of.join(body._OutsideFunc);
9572  } else {
9573  parallel_for(re, body);
9574  }
9575 }
9576 
9577 // -----------------------------------------------------------------------------
9578 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9579 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9580 {
9581  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9582  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
9583 }
9584 
9585 // -----------------------------------------------------------------------------
9586 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9587 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9588 {
9590  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
9591 }
9592 
9593 // -----------------------------------------------------------------------------
9594 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9595 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9596 {
9597  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9598  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
9599 }
9600 
9601 // -----------------------------------------------------------------------------
9602 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9603 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
9604 {
9605  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
9606  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9607  parallel_reduce(re, body);
9608  vf.join(body._VoxelFunc);
9609  of.join(body._OutsideFunc);
9610  } else {
9611  parallel_for(re, body);
9612  }
9613 }
9614 
9615 // -----------------------------------------------------------------------------
9616 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9617 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9618 {
9619  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9620  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
9621 }
9622 
9623 // -----------------------------------------------------------------------------
9624 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9625 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9626 {
9628  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
9629 }
9630 
9631 // -----------------------------------------------------------------------------
9632 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9633 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9634 {
9635  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9636  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
9637 }
9638 
9639 // -----------------------------------------------------------------------------
9640 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9641 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf, OutsideFunc &of)
9642 {
9643  QuinaryForEachVoxelIfBody<T1, T2, T3, T4, T5, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, *im4, *im5, vf, of);
9644  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9645  parallel_reduce(re, body);
9646  vf.join(body._VoxelFunc);
9647  of.join(body._OutsideFunc);
9648  } else {
9649  parallel_for(re, body);
9650  }
9651 }
9652 
9653 // -----------------------------------------------------------------------------
9654 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9655 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9656 {
9657  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9658  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
9659 }
9660 
9661 // -----------------------------------------------------------------------------
9662 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9663 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5, VoxelFunc &vf)
9664 {
9666  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf, of);
9667 }
9668 
9669 // -----------------------------------------------------------------------------
9670 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9671 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, GenericImage<T4> *im4, GenericImage<T5> *im5)
9672 {
9673  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9674  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, *im4, *im5, vf);
9675 }
9676 
9677 //
9678 // Image arguments by reference
9679 //
9680 
9681 // -----------------------------------------------------------------------------
9682 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9683 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9684 {
9687  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9688  parallel_reduce(re, body);
9689  vf.join(body._VoxelFunc);
9690  of.join(body._OutsideFunc);
9691  } else {
9692  parallel_for(re, body);
9693  }
9694 }
9695 
9696 // -----------------------------------------------------------------------------
9697 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9698 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9699 {
9700  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9701  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9702 }
9703 
9704 // -----------------------------------------------------------------------------
9705 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9706 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9707 {
9709  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9710 }
9711 
9712 // -----------------------------------------------------------------------------
9713 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9714 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9715 {
9716  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9717  ParallelForEachScalarIf<Domain>(im1, im2, im3, im4, im5, vf);
9718 }
9719 
9720 // -----------------------------------------------------------------------------
9721 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9722 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9723 {
9724  if (im5.GetTSize()) {
9725  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9726  } else {
9728  blocked_range<int> re(0, im5.GetNumberOfVoxels() / im5.GetT());
9729  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9730  parallel_reduce(re, body);
9731  vf.join(body._VoxelFunc);
9732  of.join(body._OutsideFunc);
9733  } else {
9734  parallel_for(re, body);
9735  }
9736  }
9737 }
9738 
9739 // -----------------------------------------------------------------------------
9740 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9741 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9742 {
9743  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9744  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9745 }
9746 
9747 // -----------------------------------------------------------------------------
9748 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9749 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9750 {
9752  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf, of);
9753 }
9754 
9755 // -----------------------------------------------------------------------------
9756 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9757 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9758 {
9759  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9760  ParallelForEachVoxelIf<Domain>(im1, im2, im3, im4, im5, vf);
9761 }
9762 
9763 // -----------------------------------------------------------------------------
9764 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9765 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9766 {
9768  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
9769  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9770  if (attr._dt) {
9771  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
9772  } else {
9773  parallel_reduce(re, body);
9774  }
9775  vf.join(body._VoxelFunc);
9776  of.join(body._OutsideFunc);
9777  } else {
9778  if (attr._dt) {
9779  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
9780  } else {
9781  parallel_for(re, body);
9782  }
9783  }
9784 }
9785 
9786 // -----------------------------------------------------------------------------
9787 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9788 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9789 {
9790  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9791  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
9792 }
9793 
9794 // -----------------------------------------------------------------------------
9795 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9796 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9797 {
9799  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf, of);
9800 }
9801 
9802 // -----------------------------------------------------------------------------
9803 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9804 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9805 {
9806  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9807  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, im4, im5, vf);
9808 }
9809 
9810 // -----------------------------------------------------------------------------
9811 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9812 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9813 {
9815  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9816  parallel_reduce(re, body);
9817  vf.join(body._VoxelFunc);
9818  of.join(body._OutsideFunc);
9819  } else {
9820  parallel_for(re, body);
9821  }
9822 }
9823 
9824 // -----------------------------------------------------------------------------
9825 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9826 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9827 {
9828  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9829  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9830 }
9831 
9832 // -----------------------------------------------------------------------------
9833 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9834 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9835 {
9837  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9838 }
9839 
9840 // -----------------------------------------------------------------------------
9841 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9842 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9843 {
9844  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9845  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
9846 }
9847 
9848 // -----------------------------------------------------------------------------
9849 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9850 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9851 {
9853  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9854  parallel_reduce(re, body);
9855  vf.join(body._VoxelFunc);
9856  of.join(body._OutsideFunc);
9857  } else {
9858  parallel_for(re, body);
9859  }
9860 }
9861 
9862 // -----------------------------------------------------------------------------
9863 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9864 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9865 {
9866  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9867  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9868 }
9869 
9870 // -----------------------------------------------------------------------------
9871 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9872 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9873 {
9875  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9876 }
9877 
9878 // -----------------------------------------------------------------------------
9879 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9880 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9881 {
9882  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9883  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
9884 }
9885 
9886 // -----------------------------------------------------------------------------
9887 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9888 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf, OutsideFunc &of)
9889 {
9891  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
9892  parallel_reduce(re, body);
9893  vf.join(body._VoxelFunc);
9894  of.join(body._OutsideFunc);
9895  } else {
9896  parallel_for(re, body);
9897  }
9898 }
9899 
9900 // -----------------------------------------------------------------------------
9901 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc, class OutsideFunc>
9902 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9903 {
9904  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9905  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9906 }
9907 
9908 // -----------------------------------------------------------------------------
9909 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9910 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5, VoxelFunc &vf)
9911 {
9913  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf, of);
9914 }
9915 
9916 // -----------------------------------------------------------------------------
9917 template <class Domain, class T1, class T2, class T3, class T4, class T5, class VoxelFunc>
9918 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, GenericImage<T4> &im4, GenericImage<T5> &im5)
9919 {
9920  if (VoxelFunc::IsReduction()) _foreachquinaryvoxelfunction_must_not_be_reduction();
9921  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, im4, im5, vf);
9922 }
9923 
9924 
9925 } // namespace mirtk
9926 
9927 #endif
double _dt
Voxel t-dimensions (in ms)
QuinaryForEachVoxelBody_Const(QuinaryForEachVoxelBody_Const &o, split s)
Split constructor.
QuinaryForEachVoxelIfBody_1Const(const QuinaryForEachVoxelIfBody_1Const &o)
Copy constructor.
Dummy type used to distinguish split constructor from copy constructor.
Definition: Parallel.h:143
QuinaryForEachVoxelBody_3Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf)
Constructor.
QuinaryForEachVoxelBody_2Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf)
Constructor.
QuinaryForEachVoxelIfBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf, OutsideFunc &of)
Constructor.
QuinaryForEachVoxelBody_Const(const QuinaryForEachVoxelBody_Const &o)
Copy constructor.
QuinaryForEachVoxelBody(const QuinaryForEachVoxelBody &o)
Copy constructor.
Two-dimensional range.
Definition: Parallel.h:168
QuinaryForEachVoxelIfBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, const GenericImage< T4 > &im4, const GenericImage< T5 > &im5, VoxelFunc &vf, OutsideFunc &of)
Constructor.
bool IsEmpty() const
Whether image is uninitialized.
Definition: BaseImage.h:1283
QuinaryForEachVoxelBody_1Const(const QuinaryForEachVoxelBody_1Const &o)
Copy constructor.
QuinaryForEachVoxelBody(QuinaryForEachVoxelBody &o, split s)
Split constructor.
QuinaryForEachVoxelIfBody_3Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf, OutsideFunc &of)
Constructor.
int _y
Image y-dimension (in voxels)
QuinaryForEachVoxelIfBody_3Const(QuinaryForEachVoxelIfBody_3Const &o, split s)
Split constructor.
One-dimensional range.
Definition: Parallel.h:155
QuinaryForEachVoxelIfBody_2Const(const QuinaryForEachVoxelIfBody_2Const &o)
Copy constructor.
QuinaryForEachVoxelBody_4Const(const QuinaryForEachVoxelBody_4Const &o)
Copy constructor.
QuinaryForEachVoxelBody_2Const(const QuinaryForEachVoxelBody_2Const &o)
Copy constructor.
VoxelFunc _VoxelFunc
Functor executed for each voxel.
QuinaryForEachVoxelIfBody_4Const(QuinaryForEachVoxelIfBody_4Const &o, split s)
Split constructor.
QuinaryForEachVoxelIfBody_1Const(QuinaryForEachVoxelIfBody_1Const &o, split s)
Split constructor.
QuinaryForEachVoxelIfBody_2Const(QuinaryForEachVoxelIfBody_2Const &o, split s)
Split constructor.
QuinaryForEachVoxelBody_2Const(QuinaryForEachVoxelBody_2Const &o, split s)
Split constructor.
void operator()(const ImageAttributes &attr) const
Process entire image.
QuinaryForEachVoxelIfBody_4Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, const GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf, OutsideFunc &of)
Constructor.
QuinaryForEachVoxelIfBody_3Const(const QuinaryForEachVoxelIfBody_3Const &o)
Copy constructor.
Definition: IOConfig.h:41
QuinaryForEachVoxelIfBody_2Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf, OutsideFunc &of)
Constructor.
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.
int _t
Image t-dimension (in voxels)
QuinaryForEachVoxelIfBody(QuinaryForEachVoxelIfBody &o, split s)
Split constructor.
int GetT() const
Returns the number of voxels in the t-direction.
Definition: BaseImage.h:922
QuinaryForEachVoxelIfBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf, OutsideFunc &of)
Constructor.
QuinaryForEachVoxelBody_4Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, const GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf)
Constructor.
QuinaryForEachVoxelBody_3Const(QuinaryForEachVoxelBody_3Const &o, split s)
Split constructor.
QuinaryForEachVoxelIfBody(const QuinaryForEachVoxelIfBody &o)
Copy constructor.
int GetY() const
Returns the number of voxels in the y-direction.
Definition: BaseImage.h:910
QuinaryForEachVoxelIfBody_Const(const QuinaryForEachVoxelIfBody_Const &o)
Copy constructor.
QuinaryForEachVoxelBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf)
Constructor.
Three-dimensional range.
Definition: Parallel.h:197
int GetNumberOfVoxels() const
Definition: BaseImage.h:1741
OutsideFunc _OutsideFunc
Functor executed for each background voxel.
QuinaryForEachVoxelBody_3Const(const QuinaryForEachVoxelBody_3Const &o)
Copy constructor.
QuinaryForEachVoxelBody_1Const(QuinaryForEachVoxelBody_1Const &o, split s)
Split constructor.
double GetTSize() const
Returns the size of a voxel in the t-direction.
Definition: BaseImage.h:970
QuinaryForEachVoxelIfBody_Const(QuinaryForEachVoxelIfBody_Const &o, split s)
Split constructor.
QuinaryForEachVoxelBody_4Const(QuinaryForEachVoxelBody_4Const &o, split s)
Split constructor.
QuinaryForEachVoxelBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, GenericImage< T4 > &im4, GenericImage< T5 > &im5, VoxelFunc &vf)
Constructor.
QuinaryForEachVoxelBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, const GenericImage< T4 > &im4, const GenericImage< T5 > &im5, VoxelFunc &vf)
Constructor.
int _x
Image x-dimension (in voxels)
void parallel_reduce(const Range &range, Body &body)
parallel_reduce dummy template function which executes the body serially
Definition: Parallel.h:238
QuinaryForEachVoxelIfBody_4Const(const QuinaryForEachVoxelIfBody_4Const &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