ForEachBinaryVoxelFunction.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_ForEachBinaryVoxelFunction_H
31 #define MIRTK_ForEachBinaryVoxelFunction_H
32 
33 #include "mirtk/Stream.h"
34 #include "mirtk/VoxelFunction.h"
35 
36 
37 namespace mirtk {
38 
39 
40 inline void _foreachbinaryvoxelfunction_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 // 2 const images
50 // =============================================================================
51 
52 // -----------------------------------------------------------------------------
53 /**
54  * ForEachVoxel body for voxel function of 2 const images
55  */
56 template <class T1, class T2, class VoxelFunc>
58 {
59  const GenericImage<T1> &im1;
60  const GenericImage<T2> &im2;
61 
62  /// Constructor
64  const GenericImage<T2> &im2,
65  VoxelFunc &vf)
66  :
67  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2)
68  {}
69 
70  /// Copy constructor
72  :
73  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2)
74  {}
75 
76  /// Split constructor
78  :
79  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2)
80  {}
81 
82  /// Process entire image
83  void operator ()(const ImageAttributes &attr) const
84  {
85  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
86  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
87 
88  const int T = (attr._dt ? attr._t : 1);
89 
90  for (int l = 0; l < T; ++l)
91  for (int k = 0; k < attr._z; ++k)
92  for (int j = 0; j < attr._y; ++j)
93  for (int i = 0; i < attr._x; ++i, ++p1, ++p2) {
94  // const_cast such that voxel functions need only implement
95  // non-const operator() which is required for parallel_reduce
96  const_cast<BinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2);
97  }
98  }
99 
100  /// Process image region using linear index
101  void operator ()(const blocked_range<int> &re) const
102  {
103  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
104  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
105 
106  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1) {
107  // const_cast such that voxel functions need only implement
108  // non-const operator() which is required for parallel_reduce
109  const_cast<BinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(im2, idx, p1, p2);
110  }
111  }
112 
113  /// Process 2D image region
114  void operator ()(const blocked_range2d<int> &re) const
115  {
116  const int bi = re.cols().begin();
117  const int bj = re.rows().begin();
118  const int ei = re.cols().end();
119  const int ej = re.rows().end();
120 
121  const int s1 = im2.GetX() - (ei - bi);
122 
123  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
124  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
125 
126  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
127  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
128  // const_cast such that voxel functions need only implement
129  // non-const operator() which is required for parallel_reduce
130  const_cast<BinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2);
131  }
132  }
133 
134  /// Process 3D image region
135  void operator ()(const blocked_range3d<int> &re) const
136  {
137  const int bi = re.cols ().begin();
138  const int bj = re.rows ().begin();
139  const int bk = re.pages().begin();
140  const int ei = re.cols ().end();
141  const int ej = re.rows ().end();
142  const int ek = re.pages().end();
143 
144  const int s1 = im2.GetX() - (ei - bi);
145  const int s2 = (im2.GetY() - (ej - bj)) * im2.GetX();
146 
147  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
148  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
149 
150  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2)
151  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
152  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
153  // const_cast such that voxel functions need only implement
154  // non-const operator() which is required for parallel_reduce
155  const_cast<BinaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2);
156  }
157  }
158 };
159 
160 // -----------------------------------------------------------------------------
161 /**
162  * ForEachVoxel body for inside and outside unary voxel function of 2 const images
163  */
164 template <class T1, class T2,
165  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
166  class Domain = ForEachVoxelDomain::Foreground>
167 struct BinaryForEachVoxelIfBody_Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
168 {
169  const GenericImage<T1> &im1;
170  const GenericImage<T2> &im2;
171 
172  /// Constructor
174  const GenericImage<T2> &im2,
175  VoxelFunc &vf, OutsideFunc &of)
176  :
177  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2)
178  {}
179 
180  /// Copy constructor
182  :
183  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2)
184  {}
185 
186  /// Split constructor
188  :
189  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2)
190  {}
191 
192  /// Process entire image
193  void operator ()(const ImageAttributes &attr) const
194  {
195  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
196  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
197 
198  const int T = (attr._dt ? attr._t : 1);
199 
200  for (int l = 0; l < T; ++l)
201  for (int k = 0; k < attr._z; ++k)
202  for (int j = 0; j < attr._y; ++j)
203  for (int i = 0; i < attr._x; ++i, ++p1, ++p2) {
204  if (Domain::IsInside(im2, i, j, k, l, p2)) {
205  // const_cast such that voxel functions need only implement
206  // non-const operator() which is required for parallel_reduce
207  const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2);
208  } else const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2);
209  }
210  }
211 
212  /// Process image region using linear index
213  void operator ()(const blocked_range<int> &re) const
214  {
215  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
216  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
217 
218  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1) {
219  if (Domain::IsInside(im2, idx, p2)) {
220  // const_cast such that voxel functions need only implement
221  // non-const operator() which is required for parallel_reduce
222  const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (im2, idx, p1, p2);
223  } else const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(im2, idx, p1, p2);
224  }
225  }
226 
227  /// Process 2D image region
228  void operator ()(const blocked_range2d<int> &re) const
229  {
230  const int bi = re.cols().begin();
231  const int bj = re.rows().begin();
232  const int ei = re.cols().end();
233  const int ej = re.rows().end();
234 
235  const int s1 = im2.GetX() - (ei - bi);
236 
237  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
238  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
239 
240  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
241  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
242  if (Domain::IsInside(im2, i, j, this->_k, this->_l, p2)) {
243  // const_cast such that voxel functions need only implement
244  // non-const operator() which is required for parallel_reduce
245  const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2);
246  } else const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2);
247  }
248  }
249 
250  /// Process 3D image region
251  void operator ()(const blocked_range3d<int> &re) const
252  {
253  const int bi = re.cols ().begin();
254  const int bj = re.rows ().begin();
255  const int bk = re.pages().begin();
256  const int ei = re.cols ().end();
257  const int ej = re.rows ().end();
258  const int ek = re.pages().end();
259 
260  const int s1 = im2.GetX() - (ei - bi);
261  const int s2 = (im2.GetY() - (ej - bj)) * im2.GetX();
262 
263  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
264  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
265 
266  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2)
267  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
268  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
269  if (Domain::IsInside(im2, i, j, k, this->_l, p2)) {
270  // const_cast such that voxel functions need only implement
271  // non-const operator() which is required for parallel_reduce
272  const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2);
273  } else const_cast<BinaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2);
274  }
275  }
276 };
277 
278 // -----------------------------------------------------------------------------
279 // ForEachVoxel
280 // -----------------------------------------------------------------------------
281 
282 //
283 // Image arguments by pointer
284 //
285 
286 // -----------------------------------------------------------------------------
287 template <class T1, class T2, class VoxelFunc>
288 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
289 {
292  body(re);
293  vf.join(body._VoxelFunc);
294 }
295 
296 // -----------------------------------------------------------------------------
297 template <class T1, class T2, class VoxelFunc>
298 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
299 {
300  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
301  ForEachScalar(*im1, *im2, vf);
302 }
303 
304 // -----------------------------------------------------------------------------
305 template <class T1, class T2, class VoxelFunc>
306 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
307 {
308  if (im2->GetTSize()) {
309  ForEachScalar(*im1, *im2, vf);
310  } else {
312  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
313  body(re);
314  vf.join(body._VoxelFunc);
315  }
316 }
317 
318 // -----------------------------------------------------------------------------
319 template <class T1, class T2, class VoxelFunc>
320 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
321 {
322  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
323  ForEachVoxel(*im1, *im2, vf);
324 }
325 
326 // -----------------------------------------------------------------------------
327 template <class T1, class T2, class VoxelFunc>
328 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
329 {
331  body(attr);
332  vf.join(body._VoxelFunc);
333 }
334 
335 // -----------------------------------------------------------------------------
336 template <class T1, class T2, class VoxelFunc>
337 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
338 {
339  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
340  ForEachVoxel(attr, *im1, *im2, vf);
341 }
342 
343 // -----------------------------------------------------------------------------
344 template <class T1, class T2, class VoxelFunc>
345 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
346 {
348  body(re);
349  vf.join(body._VoxelFunc);
350 }
351 
352 // -----------------------------------------------------------------------------
353 template <class T1, class T2, class VoxelFunc>
354 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
355 {
356  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
357  ForEachVoxel(re, *im1, *im2, vf);
358 }
359 
360 // -----------------------------------------------------------------------------
361 template <class T1, class T2, class VoxelFunc>
362 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
363 {
365  body(re);
366  vf.join(body._VoxelFunc);
367 }
368 
369 // -----------------------------------------------------------------------------
370 template <class T1, class T2, class VoxelFunc>
371 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
372 {
373  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
374  ForEachVoxel(re, *im1, *im2, vf);
375 }
376 
377 // -----------------------------------------------------------------------------
378 template <class T1, class T2, class VoxelFunc>
379 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
380 {
382  body(re);
383  vf.join(body._VoxelFunc);
384 }
385 
386 // -----------------------------------------------------------------------------
387 template <class T1, class T2, class VoxelFunc>
388 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
389 {
390  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
391  ForEachVoxel(re, *im1, *im2, vf);
392 }
393 
394 //
395 // Image arguments by reference
396 //
397 
398 // -----------------------------------------------------------------------------
399 template <class T1, class T2, class VoxelFunc>
400 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
401 {
404  body(re);
405  vf.join(body._VoxelFunc);
406 }
407 
408 // -----------------------------------------------------------------------------
409 template <class T1, class T2, class VoxelFunc>
410 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
411 {
412  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
413  ForEachScalar(im1, im2, vf);
414 }
415 
416 // -----------------------------------------------------------------------------
417 template <class T1, class T2, class VoxelFunc>
418 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
419 {
420  if (im2.GetTSize()) {
421  ForEachScalar(im1, im2, vf);
422  } else {
424  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
425  body(re);
426  vf.join(body._VoxelFunc);
427  }
428 }
429 
430 // -----------------------------------------------------------------------------
431 template <class T1, class T2, class VoxelFunc>
432 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
433 {
434  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
435  ForEachVoxel(im1, im2, vf);
436 }
437 
438 // -----------------------------------------------------------------------------
439 template <class T1, class T2, class VoxelFunc>
440 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
441 {
443  body(attr);
444  vf.join(body._VoxelFunc);
445 }
446 
447 // -----------------------------------------------------------------------------
448 template <class T1, class T2, class VoxelFunc>
449 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
450 {
451  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
452  ForEachVoxel(attr, im1, im2, vf);
453 }
454 
455 // -----------------------------------------------------------------------------
456 template <class T1, class T2, class VoxelFunc>
457 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
458 {
460  body(re);
461  vf.join(body._VoxelFunc);
462 }
463 
464 // -----------------------------------------------------------------------------
465 template <class T1, class T2, class VoxelFunc>
466 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
467 {
468  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
469  ForEachVoxel(re, im1, im2, vf);
470 }
471 
472 // -----------------------------------------------------------------------------
473 template <class T1, class T2, class VoxelFunc>
474 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
475 {
477  body(re);
478  vf.join(body._VoxelFunc);
479 }
480 
481 // -----------------------------------------------------------------------------
482 template <class T1, class T2, class VoxelFunc>
483 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
484 {
485  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
486  ForEachVoxel(re, im1, im2, vf);
487 }
488 
489 // -----------------------------------------------------------------------------
490 template <class T1, class T2, class VoxelFunc>
491 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
492 {
494  body(re);
495  vf.join(body._VoxelFunc);
496 }
497 
498 // -----------------------------------------------------------------------------
499 template <class T1, class T2, class VoxelFunc>
500 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
501 {
502  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
503  ForEachVoxel(re, im1, im2, vf);
504 }
505 
506 // -----------------------------------------------------------------------------
507 // ForEachVoxelIf
508 // -----------------------------------------------------------------------------
509 
510 //
511 // Image arguments by pointer
512 //
513 
514 // -----------------------------------------------------------------------------
515 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
516 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
517 {
520  body(re);
521  vf.join(body._VoxelFunc);
522  of.join(body._OutsideFunc);
523 }
524 
525 // -----------------------------------------------------------------------------
526 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
527 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
528 {
529  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
530  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
531 }
532 
533 // -----------------------------------------------------------------------------
534 template <class Domain, class T1, class T2, class VoxelFunc>
535 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
536 {
538  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
539 }
540 
541 // -----------------------------------------------------------------------------
542 template <class Domain, class T1, class T2, class VoxelFunc>
543 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
544 {
545  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
546  ForEachScalarIf<Domain>(*im1, *im2, vf);
547 }
548 
549 // -----------------------------------------------------------------------------
550 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
551 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
552 {
553  if (im2->GetTSize()) {
554  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
555  } else {
557  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
558  body(re);
559  vf.join(body._VoxelFunc);
560  of.join(body._OutsideFunc);
561  }
562 }
563 
564 // -----------------------------------------------------------------------------
565 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
566 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
567 {
568  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
569  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
570 }
571 
572 // -----------------------------------------------------------------------------
573 template <class Domain, class T1, class T2, class VoxelFunc>
574 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
575 {
577  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
578 }
579 
580 // -----------------------------------------------------------------------------
581 template <class Domain, class T1, class T2, class VoxelFunc>
582 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
583 {
584  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
585  ForEachVoxelIf<Domain>(*im1, *im2, vf);
586 }
587 
588 // -----------------------------------------------------------------------------
589 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
590 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
591 {
593  body(attr);
594  vf.join(body._VoxelFunc);
595  of.join(body._OutsideFunc);
596 }
597 
598 // -----------------------------------------------------------------------------
599 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
600 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
601 {
602  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
603  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
604 }
605 
606 // -----------------------------------------------------------------------------
607 template <class Domain, class T1, class T2, class VoxelFunc>
608 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
609 {
611  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
612 }
613 
614 // -----------------------------------------------------------------------------
615 template <class Domain, class T1, class T2, class VoxelFunc>
616 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
617 {
618  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
619  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf);
620 }
621 
622 // -----------------------------------------------------------------------------
623 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
624 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
625 {
627  body(re);
628  vf.join(body._VoxelFunc);
629  of.join(body._OutsideFunc);
630 }
631 
632 // -----------------------------------------------------------------------------
633 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
634 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
635 {
636  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
637  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
638 }
639 
640 // -----------------------------------------------------------------------------
641 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
642 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
643 {
645  body(re);
646  vf.join(body._VoxelFunc);
647  of.join(body._OutsideFunc);
648 }
649 
650 // -----------------------------------------------------------------------------
651 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
652 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
653 {
654  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
655  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
656 }
657 
658 // -----------------------------------------------------------------------------
659 template <class Domain, class T1, class T2, class VoxelFunc>
660 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
661 {
663  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
664 }
665 
666 // -----------------------------------------------------------------------------
667 template <class Domain, class T1, class T2, class VoxelFunc>
668 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
669 {
670  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
671  ForEachVoxelIf<Domain>(re, *im1, *im2, vf);
672 }
673 
674 // -----------------------------------------------------------------------------
675 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
676 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
677 {
679  body(re);
680  vf.join(body._VoxelFunc);
681  of.join(body._OutsideFunc);
682 }
683 
684 // -----------------------------------------------------------------------------
685 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
686 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
687 {
688  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
689  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
690 }
691 
692 // -----------------------------------------------------------------------------
693 template <class Domain, class T1, class T2, class VoxelFunc>
694 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
695 {
697  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
698 }
699 
700 // -----------------------------------------------------------------------------
701 template <class Domain, class T1, class T2, class VoxelFunc>
702 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
703 {
704  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
705  ForEachVoxelIf<Domain>(re, *im1, *im2, vf);
706 }
707 
708 //
709 // Image arguments by reference
710 //
711 
712 // -----------------------------------------------------------------------------
713 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
714 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
715 {
718  body(re);
719  vf.join(body._VoxelFunc);
720  of.join(body._OutsideFunc);
721 }
722 
723 // -----------------------------------------------------------------------------
724 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
725 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
726 {
727  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
728  ForEachScalarIf<Domain>(im1, im2, vf, of);
729 }
730 
731 // -----------------------------------------------------------------------------
732 template <class Domain, class T1, class T2, class VoxelFunc>
733 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
734 {
736  ForEachScalarIf<Domain>(im1, im2, vf, of);
737 }
738 
739 // -----------------------------------------------------------------------------
740 template <class Domain, class T1, class T2, class VoxelFunc>
741 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
742 {
743  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
744  ForEachScalarIf<Domain>(im1, im2, vf);
745 }
746 
747 // -----------------------------------------------------------------------------
748 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
749 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
750 {
751  if (im2.GetTSize()) {
752  ForEachVoxelIf<Domain>(im1, im2, vf, of);
753  } else {
755  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
756  body(re);
757  vf.join(body._VoxelFunc);
758  of.join(body._OutsideFunc);
759  }
760 }
761 
762 // -----------------------------------------------------------------------------
763 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
764 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
765 {
766  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
767  ForEachVoxelIf<Domain>(im1, im2, vf, of);
768 }
769 
770 // -----------------------------------------------------------------------------
771 template <class Domain, class T1, class T2, class VoxelFunc>
772 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
773 {
775  ForEachVoxelIf<Domain>(im1, im2, vf, of);
776 }
777 
778 // -----------------------------------------------------------------------------
779 template <class Domain, class T1, class T2, class VoxelFunc>
780 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
781 {
782  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
783  ForEachVoxelIf<Domain>(im1, im2, vf);
784 }
785 
786 // -----------------------------------------------------------------------------
787 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
788 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
789 {
791  body(attr);
792  vf.join(body._VoxelFunc);
793  of.join(body._OutsideFunc);
794 }
795 
796 // -----------------------------------------------------------------------------
797 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
798 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
799 {
800  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
801  ForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
802 }
803 
804 // -----------------------------------------------------------------------------
805 template <class Domain, class T1, class T2, class VoxelFunc>
806 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
807 {
809  ForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
810 }
811 
812 // -----------------------------------------------------------------------------
813 template <class Domain, class T1, class T2, class VoxelFunc>
814 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
815 {
816  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
817  ForEachVoxelIf<Domain>(attr, im1, im2, vf);
818 }
819 
820 // -----------------------------------------------------------------------------
821 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
822 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
823 {
825  body(re);
826  vf.join(body._VoxelFunc);
827  of.join(body._OutsideFunc);
828 }
829 
830 // -----------------------------------------------------------------------------
831 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
832 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
833 {
834  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
835  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
836 }
837 
838 // -----------------------------------------------------------------------------
839 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
840 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
841 {
843  body(re);
844  vf.join(body._VoxelFunc);
845  of.join(body._OutsideFunc);
846 }
847 
848 // -----------------------------------------------------------------------------
849 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
850 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
851 {
852  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
853  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
854 }
855 
856 // -----------------------------------------------------------------------------
857 template <class Domain, class T1, class T2, class VoxelFunc>
858 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
859 {
861  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
862 }
863 
864 // -----------------------------------------------------------------------------
865 template <class Domain, class T1, class T2, class VoxelFunc>
866 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
867 {
868  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
869  ForEachVoxelIf<Domain>(re, im1, im2, vf);
870 }
871 
872 // -----------------------------------------------------------------------------
873 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
874 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
875 {
877  body(re);
878  vf.join(body._VoxelFunc);
879  of.join(body._OutsideFunc);
880 }
881 
882 // -----------------------------------------------------------------------------
883 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
884 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
885 {
886  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
887  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
888 }
889 
890 // -----------------------------------------------------------------------------
891 template <class Domain, class T1, class T2, class VoxelFunc>
892 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
893 {
895  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
896 }
897 
898 // -----------------------------------------------------------------------------
899 template <class Domain, class T1, class T2, class VoxelFunc>
900 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
901 {
902  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
903  ForEachVoxelIf<Domain>(re, im1, im2, vf);
904 }
905 
906 // -----------------------------------------------------------------------------
907 // ParallelForEachVoxel
908 // -----------------------------------------------------------------------------
909 
910 //
911 // Image arguments by pointer
912 //
913 
914 // -----------------------------------------------------------------------------
915 template <class T1, class T2, class VoxelFunc>
916 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
917 {
920  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
921  else parallel_for (re, body);
922 }
923 
924 // -----------------------------------------------------------------------------
925 template <class T1, class T2, class VoxelFunc>
926 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
927 {
928  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
929  ParallelForEachScalar(*im1, *im2, vf);
930 }
931 
932 // -----------------------------------------------------------------------------
933 template <class T1, class T2, class VoxelFunc>
934 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
935 {
936  if (im2->GetTSize()) {
937  ParallelForEachScalar(*im1, *im2, vf);
938  } else {
940  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
941  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
942  else parallel_for (re, body);
943  }
944 }
945 
946 // -----------------------------------------------------------------------------
947 template <class T1, class T2, class VoxelFunc>
948 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
949 {
950  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
951  ParallelForEachVoxel(*im1, *im2, vf);
952 }
953 
954 // -----------------------------------------------------------------------------
955 template <class T1, class T2, class VoxelFunc>
956 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
957 {
959  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
960  if (VoxelFunc::IsReduction()) {
961  if (attr._dt) {
962  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
963  } else {
964  parallel_reduce(re, body);
965  }
966  vf.join(body._VoxelFunc);
967  } else {
968  if (attr._dt) {
969  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
970  } else {
971  parallel_for(re, body);
972  }
973  }
974 }
975 
976 // -----------------------------------------------------------------------------
977 template <class T1, class T2, class VoxelFunc>
978 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
979 {
980  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
981  ParallelForEachVoxel(attr, *im1, *im2, vf);
982 }
983 
984 // -----------------------------------------------------------------------------
985 template <class T1, class T2, class VoxelFunc>
986 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
987 {
989  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
990  else parallel_for (re, body);
991 }
992 
993 // -----------------------------------------------------------------------------
994 template <class T1, class T2, class VoxelFunc>
995 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
996 {
997  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
998  ParallelForEachVoxel(re, *im1, *im2, vf);
999 }
1000 
1001 // -----------------------------------------------------------------------------
1002 template <class T1, class T2, class VoxelFunc>
1003 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1004 {
1006  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1007  else parallel_for (re, body);
1008 }
1009 
1010 // -----------------------------------------------------------------------------
1011 template <class T1, class T2, class VoxelFunc>
1012 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1013 {
1014  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1015  ParallelForEachVoxel(re, *im1, *im2, vf);
1016 }
1017 
1018 // -----------------------------------------------------------------------------
1019 template <class T1, class T2, class VoxelFunc>
1020 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1021 {
1023  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1024  else parallel_for (re, body);
1025 }
1026 
1027 // -----------------------------------------------------------------------------
1028 template <class T1, class T2, class VoxelFunc>
1029 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1030 {
1031  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1032  ParallelForEachVoxel(re, *im1, *im2, vf);
1033 }
1034 
1035 //
1036 // Image arguments by reference
1037 //
1038 
1039 // -----------------------------------------------------------------------------
1040 template <class T1, class T2, class VoxelFunc>
1041 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1042 {
1045  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1046  else parallel_for (re, body);
1047 }
1048 
1049 // -----------------------------------------------------------------------------
1050 template <class T1, class T2, class VoxelFunc>
1051 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1052 {
1053  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1054  ParallelForEachScalar(im1, im2, vf);
1055 }
1056 
1057 // -----------------------------------------------------------------------------
1058 template <class T1, class T2, class VoxelFunc>
1059 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1060 {
1061  if (im2.GetTSize()) {
1062  ParallelForEachScalar(im1, im2, vf);
1063  } else {
1065  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
1066  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1067  else parallel_for (re, body);
1068  }
1069 }
1070 
1071 // -----------------------------------------------------------------------------
1072 template <class T1, class T2, class VoxelFunc>
1073 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1074 {
1075  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1076  ParallelForEachVoxel(im1, im2, vf);
1077 }
1078 
1079 // -----------------------------------------------------------------------------
1080 template <class T1, class T2, class VoxelFunc>
1081 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1082 {
1084  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1085  if (VoxelFunc::IsReduction()) {
1086  if (attr._dt) {
1087  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1088  } else {
1089  parallel_reduce(re, body);
1090  }
1091  vf.join(body._VoxelFunc);
1092  } else {
1093  if (attr._dt) {
1094  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1095  } else {
1096  parallel_for(re, body);
1097  }
1098  }
1099 }
1100 
1101 // -----------------------------------------------------------------------------
1102 template <class T1, class T2, class VoxelFunc>
1103 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1104 {
1105  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1106  ParallelForEachVoxel(attr, im1, im2, vf);
1107 }
1108 
1109 // -----------------------------------------------------------------------------
1110 template <class T1, class T2, class VoxelFunc>
1111 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1112 {
1114  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1115  else parallel_for (re, body);
1116 }
1117 
1118 // -----------------------------------------------------------------------------
1119 template <class T1, class T2, class VoxelFunc>
1120 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1121 {
1122  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1123  ParallelForEachVoxel(re, im1, im2, vf);
1124 }
1125 
1126 // -----------------------------------------------------------------------------
1127 template <class T1, class T2, class VoxelFunc>
1128 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1129 {
1131  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1132  else parallel_for (re, body);
1133 }
1134 
1135 // -----------------------------------------------------------------------------
1136 template <class T1, class T2, class VoxelFunc>
1137 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1138 {
1139  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1140  ParallelForEachVoxel(re, im1, im2, vf);
1141 }
1142 
1143 // -----------------------------------------------------------------------------
1144 template <class T1, class T2, class VoxelFunc>
1145 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1146 {
1148  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1149  else parallel_for (re, body);
1150 }
1151 
1152 // -----------------------------------------------------------------------------
1153 template <class T1, class T2, class VoxelFunc>
1154 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1155 {
1156  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1157  ParallelForEachVoxel(re, im1, im2, vf);
1158 }
1159 
1160 // -----------------------------------------------------------------------------
1161 // ParallelForEachVoxelIf
1162 // -----------------------------------------------------------------------------
1163 
1164 //
1165 // Image arguments by pointer
1166 //
1167 
1168 // -----------------------------------------------------------------------------
1169 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1170 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
1171 {
1173  blocked_range<int> re(0, im2->GetNumberOfVoxels());
1174  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1175  parallel_reduce(re, body);
1176  vf.join(body._VoxelFunc);
1177  of.join(body._OutsideFunc);
1178  } else {
1179  parallel_for(re, body);
1180  }
1181 }
1182 
1183 // -----------------------------------------------------------------------------
1184 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1185 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1186 {
1187  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1188  ParallelForEachScalarIf<Domain>(*im1, *im2, vf, of);
1189 }
1190 
1191 // -----------------------------------------------------------------------------
1192 template <class Domain, class T1, class T2, class VoxelFunc>
1193 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1194 {
1196  ParallelForEachScalarIf<Domain>(*im1, *im2, vf, of);
1197 }
1198 
1199 // -----------------------------------------------------------------------------
1200 template <class Domain, class T1, class T2, class VoxelFunc>
1201 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1202 {
1203  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1204  ParallelForEachScalarIf<Domain>(*im1, *im2, vf);
1205 }
1206 
1207 // -----------------------------------------------------------------------------
1208 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1209 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
1210 {
1211  if (im2->GetTSize()) {
1212  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
1213  } else {
1215  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
1216  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1217  parallel_reduce(re, body);
1218  vf.join(body._VoxelFunc);
1219  of.join(body._OutsideFunc);
1220  } else {
1221  parallel_for(re, body);
1222  }
1223  }
1224 }
1225 
1226 // -----------------------------------------------------------------------------
1227 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1228 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1229 {
1230  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1231  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
1232 }
1233 
1234 // -----------------------------------------------------------------------------
1235 template <class Domain, class T1, class T2, class VoxelFunc>
1236 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1237 {
1239  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
1240 }
1241 
1242 // -----------------------------------------------------------------------------
1243 template <class Domain, class T1, class T2, class VoxelFunc>
1244 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1245 {
1246  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1247  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf);
1248 }
1249 
1250 // -----------------------------------------------------------------------------
1251 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1252 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
1253 {
1255  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1256  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1257  if (attr._dt) {
1258  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1259  } else {
1260  parallel_reduce(re, body);
1261  }
1262  vf.join(body._VoxelFunc);
1263  of.join(body._OutsideFunc);
1264  } else {
1265  if (attr._dt) {
1266  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1267  } else {
1268  parallel_for(re, body);
1269  }
1270  }
1271 }
1272 
1273 // -----------------------------------------------------------------------------
1274 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1275 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1276 {
1277  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1278  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
1279 }
1280 
1281 // -----------------------------------------------------------------------------
1282 template <class Domain, class T1, class T2, class VoxelFunc>
1283 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1284 {
1286  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
1287 }
1288 
1289 // -----------------------------------------------------------------------------
1290 template <class Domain, class T1, class T2, class VoxelFunc>
1291 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1292 {
1293  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1294  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf);
1295 }
1296 
1297 // -----------------------------------------------------------------------------
1298 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1299 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
1300 {
1302  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1303  parallel_reduce(re, body);
1304  vf.join(body._VoxelFunc);
1305  of.join(body._OutsideFunc);
1306  } else {
1307  parallel_for(re, body);
1308  }
1309 }
1310 
1311 // -----------------------------------------------------------------------------
1312 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1313 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1314 {
1315  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1316  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
1317 }
1318 
1319 // -----------------------------------------------------------------------------
1320 template <class Domain, class T1, class T2, class VoxelFunc>
1321 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1322 {
1324  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
1325 }
1326 
1327 // -----------------------------------------------------------------------------
1328 template <class Domain, class T1, class T2, class VoxelFunc>
1329 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1330 {
1331  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1332  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
1333 }
1334 
1335 // -----------------------------------------------------------------------------
1336 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1337 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
1338 {
1340  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1341  parallel_reduce(re, body);
1342  vf.join(body._VoxelFunc);
1343  of.join(body._OutsideFunc);
1344  } else {
1345  parallel_for(re, body);
1346  }
1347 }
1348 
1349 // -----------------------------------------------------------------------------
1350 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1351 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1352 {
1353  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1354  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
1355 }
1356 
1357 // -----------------------------------------------------------------------------
1358 template <class Domain, class T1, class T2, class VoxelFunc>
1359 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1360 {
1362  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
1363 }
1364 
1365 // -----------------------------------------------------------------------------
1366 template <class Domain, class T1, class T2, class VoxelFunc>
1367 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1368 {
1369  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1370  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
1371 }
1372 
1373 // -----------------------------------------------------------------------------
1374 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1375 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
1376 {
1378  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1379  parallel_reduce(re, body);
1380  vf.join(body._VoxelFunc);
1381  of.join(body._OutsideFunc);
1382  } else {
1383  parallel_for(re, body);
1384  }
1385 }
1386 
1387 // -----------------------------------------------------------------------------
1388 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1389 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1390 {
1391  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1392  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
1393 }
1394 
1395 // -----------------------------------------------------------------------------
1396 template <class Domain, class T1, class T2, class VoxelFunc>
1397 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, VoxelFunc &vf)
1398 {
1400  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
1401 }
1402 
1403 // -----------------------------------------------------------------------------
1404 template <class Domain, class T1, class T2, class VoxelFunc>
1405 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2)
1406 {
1407  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1408  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
1409 }
1410 
1411 //
1412 // Image arguments by reference
1413 //
1414 
1415 // -----------------------------------------------------------------------------
1416 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1417 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
1418 {
1421  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1422  parallel_reduce(re, body);
1423  vf.join(body._VoxelFunc);
1424  of.join(body._OutsideFunc);
1425  } else {
1426  parallel_for(re, body);
1427  }
1428 }
1429 
1430 // -----------------------------------------------------------------------------
1431 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1432 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1433 {
1434  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1435  ParallelForEachScalarIf<Domain>(im1, im2, vf, of);
1436 }
1437 
1438 // -----------------------------------------------------------------------------
1439 template <class Domain, class T1, class T2, class VoxelFunc>
1440 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1441 {
1443  ParallelForEachScalarIf<Domain>(im1, im2, vf, of);
1444 }
1445 
1446 // -----------------------------------------------------------------------------
1447 template <class Domain, class T1, class T2, class VoxelFunc>
1448 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1449 {
1450  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1451  ParallelForEachScalarIf<Domain>(im1, im2, vf);
1452 }
1453 
1454 // -----------------------------------------------------------------------------
1455 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1456 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
1457 {
1458  if (im2.GetTSize()) {
1459  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
1460  } else {
1462  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
1463  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1464  parallel_reduce(re, body);
1465  vf.join(body._VoxelFunc);
1466  of.join(body._OutsideFunc);
1467  } else {
1468  parallel_for(re, body);
1469  }
1470  }
1471 }
1472 
1473 // -----------------------------------------------------------------------------
1474 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1475 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1476 {
1477  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1478  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
1479 }
1480 
1481 // -----------------------------------------------------------------------------
1482 template <class Domain, class T1, class T2, class VoxelFunc>
1483 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1484 {
1486  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
1487 }
1488 
1489 // -----------------------------------------------------------------------------
1490 template <class Domain, class T1, class T2, class VoxelFunc>
1491 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1492 {
1493  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1494  ParallelForEachVoxelIf<Domain>(im1, im2, vf);
1495 }
1496 
1497 // -----------------------------------------------------------------------------
1498 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1499 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
1500 {
1502  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1503  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1504  if (attr._dt) {
1505  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1506  } else {
1507  parallel_reduce(re, body);
1508  }
1509  vf.join(body._VoxelFunc);
1510  of.join(body._OutsideFunc);
1511  } else {
1512  if (attr._dt) {
1513  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1514  } else {
1515  parallel_for(re, body);
1516  }
1517  }
1518 }
1519 
1520 // -----------------------------------------------------------------------------
1521 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1522 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1523 {
1524  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1525  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
1526 }
1527 
1528 // -----------------------------------------------------------------------------
1529 template <class Domain, class T1, class T2, class VoxelFunc>
1530 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1531 {
1533  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
1534 }
1535 
1536 // -----------------------------------------------------------------------------
1537 template <class Domain, class T1, class T2, class VoxelFunc>
1538 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1539 {
1540  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1541  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf);
1542 }
1543 
1544 // -----------------------------------------------------------------------------
1545 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1546 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
1547 {
1549  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1550  parallel_reduce(re, body);
1551  vf.join(body._VoxelFunc);
1552  of.join(body._OutsideFunc);
1553  } else {
1554  parallel_for(re, body);
1555  }
1556 }
1557 
1558 // -----------------------------------------------------------------------------
1559 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1560 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1561 {
1562  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1563  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
1564 }
1565 
1566 // -----------------------------------------------------------------------------
1567 template <class Domain, class T1, class T2, class VoxelFunc>
1568 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1569 {
1571  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
1572 }
1573 
1574 // -----------------------------------------------------------------------------
1575 template <class Domain, class T1, class T2, class VoxelFunc>
1576 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1577 {
1578  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1579  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
1580 }
1581 
1582 // -----------------------------------------------------------------------------
1583 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1584 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
1585 {
1587  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1588  parallel_reduce(re, body);
1589  vf.join(body._VoxelFunc);
1590  of.join(body._OutsideFunc);
1591  } else {
1592  parallel_for(re, body);
1593  }
1594 }
1595 
1596 // -----------------------------------------------------------------------------
1597 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1598 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1599 {
1600  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1601  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
1602 }
1603 
1604 // -----------------------------------------------------------------------------
1605 template <class Domain, class T1, class T2, class VoxelFunc>
1606 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1607 {
1609  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
1610 }
1611 
1612 // -----------------------------------------------------------------------------
1613 template <class Domain, class T1, class T2, class VoxelFunc>
1614 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1615 {
1616  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1617  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
1618 }
1619 
1620 // -----------------------------------------------------------------------------
1621 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1622 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
1623 {
1625  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1626  parallel_reduce(re, body);
1627  vf.join(body._VoxelFunc);
1628  of.join(body._OutsideFunc);
1629  } else {
1630  parallel_for(re, body);
1631  }
1632 }
1633 
1634 // -----------------------------------------------------------------------------
1635 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
1636 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1637 {
1638  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1639  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
1640 }
1641 
1642 // -----------------------------------------------------------------------------
1643 template <class Domain, class T1, class T2, class VoxelFunc>
1644 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, VoxelFunc &vf)
1645 {
1647  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
1648 }
1649 
1650 // -----------------------------------------------------------------------------
1651 template <class Domain, class T1, class T2, class VoxelFunc>
1652 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2)
1653 {
1654  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1655  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
1656 }
1657 
1658 // =============================================================================
1659 // 1 const, 1 non-const images
1660 // =============================================================================
1661 
1662 // -----------------------------------------------------------------------------
1663 /**
1664  * ForEachVoxel body for voxel function of 1 const, 1 non-const images
1665  */
1666 template <class T1, class T2, class VoxelFunc>
1668 {
1669  const GenericImage<T1> &im1;
1670  GenericImage<T2> &im2;
1671 
1672  /// Constructor
1674  GenericImage<T2> &im2,
1675  VoxelFunc &vf)
1676  :
1677  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2)
1678  {}
1679 
1680  /// Copy constructor
1682  :
1683  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2)
1684  {}
1685 
1686  /// Split constructor
1688  :
1689  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2)
1690  {}
1691 
1692  /// Process entire image
1693  void operator ()(const ImageAttributes &attr) const
1694  {
1695  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1696  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1697 
1698  const int T = (attr._dt ? attr._t : 1);
1699 
1700  for (int l = 0; l < T; ++l)
1701  for (int k = 0; k < attr._z; ++k)
1702  for (int j = 0; j < attr._y; ++j)
1703  for (int i = 0; i < attr._x; ++i, ++p1, ++p2) {
1704  // const_cast such that voxel functions need only implement
1705  // non-const operator() which is required for parallel_reduce
1706  const_cast<BinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2);
1707  }
1708  }
1709 
1710  /// Process image region using linear index
1711  void operator ()(const blocked_range<int> &re) const
1712  {
1713  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1714  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1715 
1716  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1) {
1717  // const_cast such that voxel functions need only implement
1718  // non-const operator() which is required for parallel_reduce
1719  const_cast<BinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(im2, idx, p1, p2);
1720  }
1721  }
1722 
1723  /// Process 2D image region
1724  void operator ()(const blocked_range2d<int> &re) const
1725  {
1726  const int bi = re.cols().begin();
1727  const int bj = re.rows().begin();
1728  const int ei = re.cols().end();
1729  const int ej = re.rows().end();
1730 
1731  const int s1 = im2.GetX() - (ei - bi);
1732 
1733  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1734  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1735 
1736  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
1737  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
1738  // const_cast such that voxel functions need only implement
1739  // non-const operator() which is required for parallel_reduce
1740  const_cast<BinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2);
1741  }
1742  }
1743 
1744  /// Process 3D image region
1745  void operator ()(const blocked_range3d<int> &re) const
1746  {
1747  const int bi = re.cols ().begin();
1748  const int bj = re.rows ().begin();
1749  const int bk = re.pages().begin();
1750  const int ei = re.cols ().end();
1751  const int ej = re.rows ().end();
1752  const int ek = re.pages().end();
1753 
1754  const int s1 = im2.GetX() - (ei - bi);
1755  const int s2 = (im2.GetY() - (ej - bj)) * im2.GetX();
1756 
1757  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1758  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1759 
1760  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2)
1761  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
1762  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
1763  // const_cast such that voxel functions need only implement
1764  // non-const operator() which is required for parallel_reduce
1765  const_cast<BinaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2);
1766  }
1767  }
1768 };
1769 
1770 // -----------------------------------------------------------------------------
1771 /**
1772  * ForEachVoxel body for inside and outside unary voxel function of 1 const, 1 non-const images
1773  */
1774 template <class T1, class T2,
1775  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
1776  class Domain = ForEachVoxelDomain::Foreground>
1777 struct BinaryForEachVoxelIfBody_1Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
1778 {
1779  const GenericImage<T1> &im1;
1780  GenericImage<T2> &im2;
1781 
1782  /// Constructor
1784  GenericImage<T2> &im2,
1785  VoxelFunc &vf, OutsideFunc &of)
1786  :
1787  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2)
1788  {}
1789 
1790  /// Copy constructor
1792  :
1793  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2)
1794  {}
1795 
1796  /// Split constructor
1798  :
1799  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2)
1800  {}
1801 
1802  /// Process entire image
1803  void operator ()(const ImageAttributes &attr) const
1804  {
1805  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1806  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1807 
1808  const int T = (attr._dt ? attr._t : 1);
1809 
1810  for (int l = 0; l < T; ++l)
1811  for (int k = 0; k < attr._z; ++k)
1812  for (int j = 0; j < attr._y; ++j)
1813  for (int i = 0; i < attr._x; ++i, ++p1, ++p2) {
1814  if (Domain::IsInside(im2, i, j, k, l, p2)) {
1815  // const_cast such that voxel functions need only implement
1816  // non-const operator() which is required for parallel_reduce
1817  const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2);
1818  } else const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2);
1819  }
1820  }
1821 
1822  /// Process image region using linear index
1823  void operator ()(const blocked_range<int> &re) const
1824  {
1825  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1826  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1827 
1828  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1) {
1829  if (Domain::IsInside(im2, idx, p2)) {
1830  // const_cast such that voxel functions need only implement
1831  // non-const operator() which is required for parallel_reduce
1832  const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (im2, idx, p1, p2);
1833  } else const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(im2, idx, p1, p2);
1834  }
1835  }
1836 
1837  /// Process 2D image region
1838  void operator ()(const blocked_range2d<int> &re) const
1839  {
1840  const int bi = re.cols().begin();
1841  const int bj = re.rows().begin();
1842  const int ei = re.cols().end();
1843  const int ej = re.rows().end();
1844 
1845  const int s1 = im2.GetX() - (ei - bi);
1846 
1847  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1848  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1849 
1850  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
1851  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
1852  if (Domain::IsInside(im2, i, j, this->_k, this->_l, p2)) {
1853  // const_cast such that voxel functions need only implement
1854  // non-const operator() which is required for parallel_reduce
1855  const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2);
1856  } else const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2);
1857  }
1858  }
1859 
1860  /// Process 3D image region
1861  void operator ()(const blocked_range3d<int> &re) const
1862  {
1863  const int bi = re.cols ().begin();
1864  const int bj = re.rows ().begin();
1865  const int bk = re.pages().begin();
1866  const int ei = re.cols ().end();
1867  const int ej = re.rows ().end();
1868  const int ek = re.pages().end();
1869 
1870  const int s1 = im2.GetX() - (ei - bi);
1871  const int s2 = (im2.GetY() - (ej - bj)) * im2.GetX();
1872 
1873  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1874  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1875 
1876  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2)
1877  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
1878  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
1879  if (Domain::IsInside(im2, i, j, k, this->_l, p2)) {
1880  // const_cast such that voxel functions need only implement
1881  // non-const operator() which is required for parallel_reduce
1882  const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2);
1883  } else const_cast<BinaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2);
1884  }
1885  }
1886 };
1887 
1888 // -----------------------------------------------------------------------------
1889 // ForEachVoxel
1890 // -----------------------------------------------------------------------------
1891 
1892 //
1893 // Image arguments by pointer
1894 //
1895 
1896 // -----------------------------------------------------------------------------
1897 template <class T1, class T2, class VoxelFunc>
1898 void ForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
1899 {
1901  blocked_range<int> re(0, im2->GetNumberOfVoxels());
1902  body(re);
1903  vf.join(body._VoxelFunc);
1904 }
1905 
1906 // -----------------------------------------------------------------------------
1907 template <class T1, class T2, class VoxelFunc>
1908 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
1909 {
1910  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1911  ForEachScalar(*im1, *im2, vf);
1912 }
1913 
1914 // -----------------------------------------------------------------------------
1915 template <class T1, class T2, class VoxelFunc>
1916 void ForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
1917 {
1918  if (im2->GetTSize()) {
1919  ForEachScalar(*im1, *im2, vf);
1920  } else {
1922  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
1923  body(re);
1924  vf.join(body._VoxelFunc);
1925  }
1926 }
1927 
1928 // -----------------------------------------------------------------------------
1929 template <class T1, class T2, class VoxelFunc>
1930 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
1931 {
1932  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1933  ForEachVoxel(*im1, *im2, vf);
1934 }
1935 
1936 // -----------------------------------------------------------------------------
1937 template <class T1, class T2, class VoxelFunc>
1938 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
1939 {
1941  body(attr);
1942  vf.join(body._VoxelFunc);
1943 }
1944 
1945 // -----------------------------------------------------------------------------
1946 template <class T1, class T2, class VoxelFunc>
1947 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2)
1948 {
1949  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1950  ForEachVoxel(attr, *im1, *im2, vf);
1951 }
1952 
1953 // -----------------------------------------------------------------------------
1954 template <class T1, class T2, class VoxelFunc>
1955 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
1956 {
1958  body(re);
1959  vf.join(body._VoxelFunc);
1960 }
1961 
1962 // -----------------------------------------------------------------------------
1963 template <class T1, class T2, class VoxelFunc>
1964 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
1965 {
1966  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1967  ForEachVoxel(re, *im1, *im2, vf);
1968 }
1969 
1970 // -----------------------------------------------------------------------------
1971 template <class T1, class T2, class VoxelFunc>
1972 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
1973 {
1975  body(re);
1976  vf.join(body._VoxelFunc);
1977 }
1978 
1979 // -----------------------------------------------------------------------------
1980 template <class T1, class T2, class VoxelFunc>
1981 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
1982 {
1983  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
1984  ForEachVoxel(re, *im1, *im2, vf);
1985 }
1986 
1987 // -----------------------------------------------------------------------------
1988 template <class T1, class T2, class VoxelFunc>
1989 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
1990 {
1992  body(re);
1993  vf.join(body._VoxelFunc);
1994 }
1995 
1996 // -----------------------------------------------------------------------------
1997 template <class T1, class T2, class VoxelFunc>
1998 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
1999 {
2000  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2001  ForEachVoxel(re, *im1, *im2, vf);
2002 }
2003 
2004 //
2005 // Image arguments by reference
2006 //
2007 
2008 // -----------------------------------------------------------------------------
2009 template <class T1, class T2, class VoxelFunc>
2010 void ForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2011 {
2014  body(re);
2015  vf.join(body._VoxelFunc);
2016 }
2017 
2018 // -----------------------------------------------------------------------------
2019 template <class T1, class T2, class VoxelFunc>
2020 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2021 {
2022  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2023  ForEachScalar(im1, im2, vf);
2024 }
2025 
2026 // -----------------------------------------------------------------------------
2027 template <class T1, class T2, class VoxelFunc>
2028 void ForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2029 {
2030  if (im2.GetTSize()) {
2031  ForEachScalar(im1, im2, vf);
2032  } else {
2034  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
2035  body(re);
2036  vf.join(body._VoxelFunc);
2037  }
2038 }
2039 
2040 // -----------------------------------------------------------------------------
2041 template <class T1, class T2, class VoxelFunc>
2042 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2043 {
2044  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2045  ForEachVoxel(im1, im2, vf);
2046 }
2047 
2048 // -----------------------------------------------------------------------------
2049 template <class T1, class T2, class VoxelFunc>
2050 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2051 {
2053  body(attr);
2054  vf.join(body._VoxelFunc);
2055 }
2056 
2057 // -----------------------------------------------------------------------------
2058 template <class T1, class T2, class VoxelFunc>
2059 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2060 {
2061  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2062  ForEachVoxel(attr, im1, im2, vf);
2063 }
2064 
2065 // -----------------------------------------------------------------------------
2066 template <class T1, class T2, class VoxelFunc>
2067 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2068 {
2070  body(re);
2071  vf.join(body._VoxelFunc);
2072 }
2073 
2074 // -----------------------------------------------------------------------------
2075 template <class T1, class T2, class VoxelFunc>
2076 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2077 {
2078  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2079  ForEachVoxel(re, im1, im2, vf);
2080 }
2081 
2082 // -----------------------------------------------------------------------------
2083 template <class T1, class T2, class VoxelFunc>
2084 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2085 {
2087  body(re);
2088  vf.join(body._VoxelFunc);
2089 }
2090 
2091 // -----------------------------------------------------------------------------
2092 template <class T1, class T2, class VoxelFunc>
2093 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2094 {
2095  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2096  ForEachVoxel(re, im1, im2, vf);
2097 }
2098 
2099 // -----------------------------------------------------------------------------
2100 template <class T1, class T2, class VoxelFunc>
2101 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2102 {
2104  body(re);
2105  vf.join(body._VoxelFunc);
2106 }
2107 
2108 // -----------------------------------------------------------------------------
2109 template <class T1, class T2, class VoxelFunc>
2110 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2111 {
2112  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2113  ForEachVoxel(re, im1, im2, vf);
2114 }
2115 
2116 // -----------------------------------------------------------------------------
2117 // ForEachVoxelIf
2118 // -----------------------------------------------------------------------------
2119 
2120 //
2121 // Image arguments by pointer
2122 //
2123 
2124 // -----------------------------------------------------------------------------
2125 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2126 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2127 {
2129  blocked_range<int> re(0, im2->GetNumberOfVoxels());
2130  body(re);
2131  vf.join(body._VoxelFunc);
2132  of.join(body._OutsideFunc);
2133 }
2134 
2135 // -----------------------------------------------------------------------------
2136 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2137 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2138 {
2139  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2140  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
2141 }
2142 
2143 // -----------------------------------------------------------------------------
2144 template <class Domain, class T1, class T2, class VoxelFunc>
2145 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2146 {
2148  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
2149 }
2150 
2151 // -----------------------------------------------------------------------------
2152 template <class Domain, class T1, class T2, class VoxelFunc>
2153 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2154 {
2155  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2156  ForEachScalarIf<Domain>(*im1, *im2, vf);
2157 }
2158 
2159 // -----------------------------------------------------------------------------
2160 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2161 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2162 {
2163  if (im2->GetTSize()) {
2164  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
2165  } else {
2167  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
2168  body(re);
2169  vf.join(body._VoxelFunc);
2170  of.join(body._OutsideFunc);
2171  }
2172 }
2173 
2174 // -----------------------------------------------------------------------------
2175 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2176 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2177 {
2178  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2179  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
2180 }
2181 
2182 // -----------------------------------------------------------------------------
2183 template <class Domain, class T1, class T2, class VoxelFunc>
2184 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2185 {
2187  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
2188 }
2189 
2190 // -----------------------------------------------------------------------------
2191 template <class Domain, class T1, class T2, class VoxelFunc>
2192 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2193 {
2194  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2195  ForEachVoxelIf<Domain>(*im1, *im2, vf);
2196 }
2197 
2198 // -----------------------------------------------------------------------------
2199 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2200 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2201 {
2203  body(attr);
2204  vf.join(body._VoxelFunc);
2205  of.join(body._OutsideFunc);
2206 }
2207 
2208 // -----------------------------------------------------------------------------
2209 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2210 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2211 {
2212  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2213  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
2214 }
2215 
2216 // -----------------------------------------------------------------------------
2217 template <class Domain, class T1, class T2, class VoxelFunc>
2218 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2219 {
2221  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
2222 }
2223 
2224 // -----------------------------------------------------------------------------
2225 template <class Domain, class T1, class T2, class VoxelFunc>
2226 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2227 {
2228  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2229  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf);
2230 }
2231 
2232 // -----------------------------------------------------------------------------
2233 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2234 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2235 {
2237  body(re);
2238  vf.join(body._VoxelFunc);
2239  of.join(body._OutsideFunc);
2240 }
2241 
2242 // -----------------------------------------------------------------------------
2243 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2244 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2245 {
2246  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2247  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2248 }
2249 
2250 // -----------------------------------------------------------------------------
2251 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2252 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2253 {
2255  body(re);
2256  vf.join(body._VoxelFunc);
2257  of.join(body._OutsideFunc);
2258 }
2259 
2260 // -----------------------------------------------------------------------------
2261 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2262 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2263 {
2264  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2265  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2266 }
2267 
2268 // -----------------------------------------------------------------------------
2269 template <class Domain, class T1, class T2, class VoxelFunc>
2270 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2271 {
2273  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2274 }
2275 
2276 // -----------------------------------------------------------------------------
2277 template <class Domain, class T1, class T2, class VoxelFunc>
2278 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2279 {
2280  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2281  ForEachVoxelIf<Domain>(re, *im1, *im2, vf);
2282 }
2283 
2284 // -----------------------------------------------------------------------------
2285 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2286 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2287 {
2289  body(re);
2290  vf.join(body._VoxelFunc);
2291  of.join(body._OutsideFunc);
2292 }
2293 
2294 // -----------------------------------------------------------------------------
2295 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2296 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2297 {
2298  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2299  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
2300 }
2301 
2302 // -----------------------------------------------------------------------------
2303 template <class Domain, class T1, class T2, class VoxelFunc>
2304 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2305 {
2307  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2308 }
2309 
2310 // -----------------------------------------------------------------------------
2311 template <class Domain, class T1, class T2, class VoxelFunc>
2312 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2313 {
2314  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2315  ForEachVoxelIf<Domain>(re, *im1, *im2, vf);
2316 }
2317 
2318 //
2319 // Image arguments by reference
2320 //
2321 
2322 // -----------------------------------------------------------------------------
2323 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2324 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
2325 {
2328  body(re);
2329  vf.join(body._VoxelFunc);
2330  of.join(body._OutsideFunc);
2331 }
2332 
2333 // -----------------------------------------------------------------------------
2334 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2335 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2336 {
2337  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2338  ForEachScalarIf<Domain>(im1, im2, vf, of);
2339 }
2340 
2341 // -----------------------------------------------------------------------------
2342 template <class Domain, class T1, class T2, class VoxelFunc>
2343 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2344 {
2346  ForEachScalarIf<Domain>(im1, im2, vf, of);
2347 }
2348 
2349 // -----------------------------------------------------------------------------
2350 template <class Domain, class T1, class T2, class VoxelFunc>
2351 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2352 {
2353  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2354  ForEachScalarIf<Domain>(im1, im2, vf);
2355 }
2356 
2357 // -----------------------------------------------------------------------------
2358 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2359 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
2360 {
2361  if (im2.GetTSize()) {
2362  ForEachVoxelIf<Domain>(im1, im2, vf, of);
2363  } else {
2365  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
2366  body(re);
2367  vf.join(body._VoxelFunc);
2368  of.join(body._OutsideFunc);
2369  }
2370 }
2371 
2372 // -----------------------------------------------------------------------------
2373 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2374 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2375 {
2376  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2377  ForEachVoxelIf<Domain>(im1, im2, vf, of);
2378 }
2379 
2380 // -----------------------------------------------------------------------------
2381 template <class Domain, class T1, class T2, class VoxelFunc>
2382 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2383 {
2385  ForEachVoxelIf<Domain>(im1, im2, vf, of);
2386 }
2387 
2388 // -----------------------------------------------------------------------------
2389 template <class Domain, class T1, class T2, class VoxelFunc>
2390 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2391 {
2392  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2393  ForEachVoxelIf<Domain>(im1, im2, vf);
2394 }
2395 
2396 // -----------------------------------------------------------------------------
2397 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2398 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
2399 {
2401  body(attr);
2402  vf.join(body._VoxelFunc);
2403  of.join(body._OutsideFunc);
2404 }
2405 
2406 // -----------------------------------------------------------------------------
2407 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2408 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2409 {
2410  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2411  ForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
2412 }
2413 
2414 // -----------------------------------------------------------------------------
2415 template <class Domain, class T1, class T2, class VoxelFunc>
2416 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2417 {
2419  ForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
2420 }
2421 
2422 // -----------------------------------------------------------------------------
2423 template <class Domain, class T1, class T2, class VoxelFunc>
2424 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2425 {
2426  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2427  ForEachVoxelIf<Domain>(attr, im1, im2, vf);
2428 }
2429 
2430 // -----------------------------------------------------------------------------
2431 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2432 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
2433 {
2435  body(re);
2436  vf.join(body._VoxelFunc);
2437  of.join(body._OutsideFunc);
2438 }
2439 
2440 // -----------------------------------------------------------------------------
2441 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2442 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2443 {
2444  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2445  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
2446 }
2447 
2448 // -----------------------------------------------------------------------------
2449 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2450 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
2451 {
2453  body(re);
2454  vf.join(body._VoxelFunc);
2455  of.join(body._OutsideFunc);
2456 }
2457 
2458 // -----------------------------------------------------------------------------
2459 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2460 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2461 {
2462  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2463  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
2464 }
2465 
2466 // -----------------------------------------------------------------------------
2467 template <class Domain, class T1, class T2, class VoxelFunc>
2468 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2469 {
2471  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
2472 }
2473 
2474 // -----------------------------------------------------------------------------
2475 template <class Domain, class T1, class T2, class VoxelFunc>
2476 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2477 {
2478  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2479  ForEachVoxelIf<Domain>(re, im1, im2, vf);
2480 }
2481 
2482 // -----------------------------------------------------------------------------
2483 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2484 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
2485 {
2487  body(re);
2488  vf.join(body._VoxelFunc);
2489  of.join(body._OutsideFunc);
2490 }
2491 
2492 // -----------------------------------------------------------------------------
2493 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2494 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2495 {
2496  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2497  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
2498 }
2499 
2500 // -----------------------------------------------------------------------------
2501 template <class Domain, class T1, class T2, class VoxelFunc>
2502 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2503 {
2505  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
2506 }
2507 
2508 // -----------------------------------------------------------------------------
2509 template <class Domain, class T1, class T2, class VoxelFunc>
2510 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2511 {
2512  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2513  ForEachVoxelIf<Domain>(re, im1, im2, vf);
2514 }
2515 
2516 // -----------------------------------------------------------------------------
2517 // ParallelForEachVoxel
2518 // -----------------------------------------------------------------------------
2519 
2520 //
2521 // Image arguments by pointer
2522 //
2523 
2524 // -----------------------------------------------------------------------------
2525 template <class T1, class T2, class VoxelFunc>
2526 void ParallelForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2527 {
2529  blocked_range<int> re(0, im2->GetNumberOfVoxels());
2530  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2531  else parallel_for (re, body);
2532 }
2533 
2534 // -----------------------------------------------------------------------------
2535 template <class T1, class T2, class VoxelFunc>
2536 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2537 {
2538  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2539  ParallelForEachScalar(*im1, *im2, vf);
2540 }
2541 
2542 // -----------------------------------------------------------------------------
2543 template <class T1, class T2, class VoxelFunc>
2544 void ParallelForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2545 {
2546  if (im2->GetTSize()) {
2547  ParallelForEachScalar(*im1, *im2, vf);
2548  } else {
2550  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
2551  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2552  else parallel_for (re, body);
2553  }
2554 }
2555 
2556 // -----------------------------------------------------------------------------
2557 template <class T1, class T2, class VoxelFunc>
2558 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2559 {
2560  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2561  ParallelForEachVoxel(*im1, *im2, vf);
2562 }
2563 
2564 // -----------------------------------------------------------------------------
2565 template <class T1, class T2, class VoxelFunc>
2566 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2567 {
2569  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2570  if (VoxelFunc::IsReduction()) {
2571  if (attr._dt) {
2572  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2573  } else {
2574  parallel_reduce(re, body);
2575  }
2576  vf.join(body._VoxelFunc);
2577  } else {
2578  if (attr._dt) {
2579  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2580  } else {
2581  parallel_for(re, body);
2582  }
2583  }
2584 }
2585 
2586 // -----------------------------------------------------------------------------
2587 template <class T1, class T2, class VoxelFunc>
2588 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2589 {
2590  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2591  ParallelForEachVoxel(attr, *im1, *im2, vf);
2592 }
2593 
2594 // -----------------------------------------------------------------------------
2595 template <class T1, class T2, class VoxelFunc>
2596 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2597 {
2599  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2600  else parallel_for (re, body);
2601 }
2602 
2603 // -----------------------------------------------------------------------------
2604 template <class T1, class T2, class VoxelFunc>
2605 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2606 {
2607  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2608  ParallelForEachVoxel(re, *im1, *im2, vf);
2609 }
2610 
2611 // -----------------------------------------------------------------------------
2612 template <class T1, class T2, class VoxelFunc>
2613 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2614 {
2616  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2617  else parallel_for (re, body);
2618 }
2619 
2620 // -----------------------------------------------------------------------------
2621 template <class T1, class T2, class VoxelFunc>
2622 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2623 {
2624  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2625  ParallelForEachVoxel(re, *im1, *im2, vf);
2626 }
2627 
2628 // -----------------------------------------------------------------------------
2629 template <class T1, class T2, class VoxelFunc>
2630 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2631 {
2633  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2634  else parallel_for (re, body);
2635 }
2636 
2637 // -----------------------------------------------------------------------------
2638 template <class T1, class T2, class VoxelFunc>
2639 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2640 {
2641  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2642  ParallelForEachVoxel(re, *im1, *im2, vf);
2643 }
2644 
2645 //
2646 // Image arguments by reference
2647 //
2648 
2649 // -----------------------------------------------------------------------------
2650 template <class T1, class T2, class VoxelFunc>
2651 void ParallelForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2652 {
2655  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2656  else parallel_for (re, body);
2657 }
2658 
2659 // -----------------------------------------------------------------------------
2660 template <class T1, class T2, class VoxelFunc>
2661 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2662 {
2663  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2664  ParallelForEachScalar(im1, im2, vf);
2665 }
2666 
2667 // -----------------------------------------------------------------------------
2668 template <class T1, class T2, class VoxelFunc>
2669 void ParallelForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2670 {
2671  if (im2.GetTSize()) {
2672  ParallelForEachScalar(im1, im2, vf);
2673  } else {
2675  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
2676  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2677  else parallel_for (re, body);
2678  }
2679 }
2680 
2681 // -----------------------------------------------------------------------------
2682 template <class T1, class T2, class VoxelFunc>
2683 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2684 {
2685  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2686  ParallelForEachVoxel(im1, im2, vf);
2687 }
2688 
2689 // -----------------------------------------------------------------------------
2690 template <class T1, class T2, class VoxelFunc>
2691 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2692 {
2694  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2695  if (VoxelFunc::IsReduction()) {
2696  if (attr._dt) {
2697  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2698  } else {
2699  parallel_reduce(re, body);
2700  }
2701  vf.join(body._VoxelFunc);
2702  } else {
2703  if (attr._dt) {
2704  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2705  } else {
2706  parallel_for(re, body);
2707  }
2708  }
2709 }
2710 
2711 // -----------------------------------------------------------------------------
2712 template <class T1, class T2, class VoxelFunc>
2713 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2714 {
2715  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2716  ParallelForEachVoxel(attr, im1, im2, vf);
2717 }
2718 
2719 // -----------------------------------------------------------------------------
2720 template <class T1, class T2, class VoxelFunc>
2721 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2722 {
2724  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2725  else parallel_for (re, body);
2726 }
2727 
2728 // -----------------------------------------------------------------------------
2729 template <class T1, class T2, class VoxelFunc>
2730 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2731 {
2732  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2733  ParallelForEachVoxel(re, im1, im2, vf);
2734 }
2735 
2736 // -----------------------------------------------------------------------------
2737 template <class T1, class T2, class VoxelFunc>
2738 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2739 {
2741  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2742  else parallel_for (re, body);
2743 }
2744 
2745 // -----------------------------------------------------------------------------
2746 template <class T1, class T2, class VoxelFunc>
2747 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2748 {
2749  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2750  ParallelForEachVoxel(re, im1, im2, vf);
2751 }
2752 
2753 // -----------------------------------------------------------------------------
2754 template <class T1, class T2, class VoxelFunc>
2755 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
2756 {
2758  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2759  else parallel_for (re, body);
2760 }
2761 
2762 // -----------------------------------------------------------------------------
2763 template <class T1, class T2, class VoxelFunc>
2764 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
2765 {
2766  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2767  ParallelForEachVoxel(re, im1, im2, vf);
2768 }
2769 
2770 // -----------------------------------------------------------------------------
2771 // ParallelForEachVoxelIf
2772 // -----------------------------------------------------------------------------
2773 
2774 //
2775 // Image arguments by pointer
2776 //
2777 
2778 // -----------------------------------------------------------------------------
2779 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2780 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2781 {
2783  blocked_range<int> re(0, im2->GetNumberOfVoxels());
2784  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2785  parallel_reduce(re, body);
2786  vf.join(body._VoxelFunc);
2787  of.join(body._OutsideFunc);
2788  } else {
2789  parallel_for(re, body);
2790  }
2791 }
2792 
2793 // -----------------------------------------------------------------------------
2794 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2795 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2796 {
2797  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2798  ParallelForEachScalarIf<Domain>(*im1, *im2, vf, of);
2799 }
2800 
2801 // -----------------------------------------------------------------------------
2802 template <class Domain, class T1, class T2, class VoxelFunc>
2803 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2804 {
2806  ParallelForEachScalarIf<Domain>(*im1, *im2, vf, of);
2807 }
2808 
2809 // -----------------------------------------------------------------------------
2810 template <class Domain, class T1, class T2, class VoxelFunc>
2811 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2812 {
2813  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2814  ParallelForEachScalarIf<Domain>(*im1, *im2, vf);
2815 }
2816 
2817 // -----------------------------------------------------------------------------
2818 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2819 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2820 {
2821  if (im2->GetTSize()) {
2822  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
2823  } else {
2825  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
2826  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2827  parallel_reduce(re, body);
2828  vf.join(body._VoxelFunc);
2829  of.join(body._OutsideFunc);
2830  } else {
2831  parallel_for(re, body);
2832  }
2833  }
2834 }
2835 
2836 // -----------------------------------------------------------------------------
2837 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2838 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2839 {
2840  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2841  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
2842 }
2843 
2844 // -----------------------------------------------------------------------------
2845 template <class Domain, class T1, class T2, class VoxelFunc>
2846 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2847 {
2849  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
2850 }
2851 
2852 // -----------------------------------------------------------------------------
2853 template <class Domain, class T1, class T2, class VoxelFunc>
2854 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2855 {
2856  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2857  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf);
2858 }
2859 
2860 // -----------------------------------------------------------------------------
2861 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2862 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2863 {
2865  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2866  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2867  if (attr._dt) {
2868  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2869  } else {
2870  parallel_reduce(re, body);
2871  }
2872  vf.join(body._VoxelFunc);
2873  of.join(body._OutsideFunc);
2874  } else {
2875  if (attr._dt) {
2876  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2877  } else {
2878  parallel_for(re, body);
2879  }
2880  }
2881 }
2882 
2883 // -----------------------------------------------------------------------------
2884 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2885 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2886 {
2887  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2888  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
2889 }
2890 
2891 // -----------------------------------------------------------------------------
2892 template <class Domain, class T1, class T2, class VoxelFunc>
2893 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2894 {
2896  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
2897 }
2898 
2899 // -----------------------------------------------------------------------------
2900 template <class Domain, class T1, class T2, class VoxelFunc>
2901 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2902 {
2903  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2904  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf);
2905 }
2906 
2907 // -----------------------------------------------------------------------------
2908 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2909 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2910 {
2912  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2913  parallel_reduce(re, body);
2914  vf.join(body._VoxelFunc);
2915  of.join(body._OutsideFunc);
2916  } else {
2917  parallel_for(re, body);
2918  }
2919 }
2920 
2921 // -----------------------------------------------------------------------------
2922 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2923 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2924 {
2925  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2926  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2927 }
2928 
2929 // -----------------------------------------------------------------------------
2930 template <class Domain, class T1, class T2, class VoxelFunc>
2931 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2932 {
2934  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2935 }
2936 
2937 // -----------------------------------------------------------------------------
2938 template <class Domain, class T1, class T2, class VoxelFunc>
2939 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2940 {
2941  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2942  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
2943 }
2944 
2945 // -----------------------------------------------------------------------------
2946 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2947 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2948 {
2950  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2951  parallel_reduce(re, body);
2952  vf.join(body._VoxelFunc);
2953  of.join(body._OutsideFunc);
2954  } else {
2955  parallel_for(re, body);
2956  }
2957 }
2958 
2959 // -----------------------------------------------------------------------------
2960 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2961 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2962 {
2963  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2964  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2965 }
2966 
2967 // -----------------------------------------------------------------------------
2968 template <class Domain, class T1, class T2, class VoxelFunc>
2969 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
2970 {
2972  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
2973 }
2974 
2975 // -----------------------------------------------------------------------------
2976 template <class Domain, class T1, class T2, class VoxelFunc>
2977 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
2978 {
2979  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
2980  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
2981 }
2982 
2983 // -----------------------------------------------------------------------------
2984 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2985 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
2986 {
2988  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2989  parallel_reduce(re, body);
2990  vf.join(body._VoxelFunc);
2991  of.join(body._OutsideFunc);
2992  } else {
2993  parallel_for(re, body);
2994  }
2995 }
2996 
2997 // -----------------------------------------------------------------------------
2998 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
2999 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
3000 {
3001  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3002  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
3003 }
3004 
3005 // -----------------------------------------------------------------------------
3006 template <class Domain, class T1, class T2, class VoxelFunc>
3007 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3008 {
3010  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
3011 }
3012 
3013 // -----------------------------------------------------------------------------
3014 template <class Domain, class T1, class T2, class VoxelFunc>
3015 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2)
3016 {
3017  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3018  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
3019 }
3020 
3021 //
3022 // Image arguments by reference
3023 //
3024 
3025 // -----------------------------------------------------------------------------
3026 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3027 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3028 {
3031  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3032  parallel_reduce(re, body);
3033  vf.join(body._VoxelFunc);
3034  of.join(body._OutsideFunc);
3035  } else {
3036  parallel_for(re, body);
3037  }
3038 }
3039 
3040 // -----------------------------------------------------------------------------
3041 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3042 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3043 {
3044  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3045  ParallelForEachScalarIf<Domain>(im1, im2, vf, of);
3046 }
3047 
3048 // -----------------------------------------------------------------------------
3049 template <class Domain, class T1, class T2, class VoxelFunc>
3050 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3051 {
3053  ParallelForEachScalarIf<Domain>(im1, im2, vf, of);
3054 }
3055 
3056 // -----------------------------------------------------------------------------
3057 template <class Domain, class T1, class T2, class VoxelFunc>
3058 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3059 {
3060  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3061  ParallelForEachScalarIf<Domain>(im1, im2, vf);
3062 }
3063 
3064 // -----------------------------------------------------------------------------
3065 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3066 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3067 {
3068  if (im2.GetTSize()) {
3069  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
3070  } else {
3072  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
3073  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3074  parallel_reduce(re, body);
3075  vf.join(body._VoxelFunc);
3076  of.join(body._OutsideFunc);
3077  } else {
3078  parallel_for(re, body);
3079  }
3080  }
3081 }
3082 
3083 // -----------------------------------------------------------------------------
3084 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3085 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3086 {
3087  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3088  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
3089 }
3090 
3091 // -----------------------------------------------------------------------------
3092 template <class Domain, class T1, class T2, class VoxelFunc>
3093 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3094 {
3096  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
3097 }
3098 
3099 // -----------------------------------------------------------------------------
3100 template <class Domain, class T1, class T2, class VoxelFunc>
3101 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3102 {
3103  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3104  ParallelForEachVoxelIf<Domain>(im1, im2, vf);
3105 }
3106 
3107 // -----------------------------------------------------------------------------
3108 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3109 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3110 {
3112  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
3113  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3114  if (attr._dt) {
3115  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
3116  } else {
3117  parallel_reduce(re, body);
3118  }
3119  vf.join(body._VoxelFunc);
3120  of.join(body._OutsideFunc);
3121  } else {
3122  if (attr._dt) {
3123  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
3124  } else {
3125  parallel_for(re, body);
3126  }
3127  }
3128 }
3129 
3130 // -----------------------------------------------------------------------------
3131 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3132 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3133 {
3134  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3135  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
3136 }
3137 
3138 // -----------------------------------------------------------------------------
3139 template <class Domain, class T1, class T2, class VoxelFunc>
3140 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3141 {
3143  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
3144 }
3145 
3146 // -----------------------------------------------------------------------------
3147 template <class Domain, class T1, class T2, class VoxelFunc>
3148 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3149 {
3150  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3151  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf);
3152 }
3153 
3154 // -----------------------------------------------------------------------------
3155 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3156 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3157 {
3159  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3160  parallel_reduce(re, body);
3161  vf.join(body._VoxelFunc);
3162  of.join(body._OutsideFunc);
3163  } else {
3164  parallel_for(re, body);
3165  }
3166 }
3167 
3168 // -----------------------------------------------------------------------------
3169 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3170 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3171 {
3172  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3173  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
3174 }
3175 
3176 // -----------------------------------------------------------------------------
3177 template <class Domain, class T1, class T2, class VoxelFunc>
3178 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3179 {
3181  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
3182 }
3183 
3184 // -----------------------------------------------------------------------------
3185 template <class Domain, class T1, class T2, class VoxelFunc>
3186 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3187 {
3188  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3189  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
3190 }
3191 
3192 // -----------------------------------------------------------------------------
3193 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3194 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3195 {
3197  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3198  parallel_reduce(re, body);
3199  vf.join(body._VoxelFunc);
3200  of.join(body._OutsideFunc);
3201  } else {
3202  parallel_for(re, body);
3203  }
3204 }
3205 
3206 // -----------------------------------------------------------------------------
3207 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3208 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3209 {
3210  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3211  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
3212 }
3213 
3214 // -----------------------------------------------------------------------------
3215 template <class Domain, class T1, class T2, class VoxelFunc>
3216 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3217 {
3219  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
3220 }
3221 
3222 // -----------------------------------------------------------------------------
3223 template <class Domain, class T1, class T2, class VoxelFunc>
3224 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3225 {
3226  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3227  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
3228 }
3229 
3230 // -----------------------------------------------------------------------------
3231 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3232 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3233 {
3235  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3236  parallel_reduce(re, body);
3237  vf.join(body._VoxelFunc);
3238  of.join(body._OutsideFunc);
3239  } else {
3240  parallel_for(re, body);
3241  }
3242 }
3243 
3244 // -----------------------------------------------------------------------------
3245 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3246 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3247 {
3248  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3249  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
3250 }
3251 
3252 // -----------------------------------------------------------------------------
3253 template <class Domain, class T1, class T2, class VoxelFunc>
3254 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3255 {
3257  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
3258 }
3259 
3260 // -----------------------------------------------------------------------------
3261 template <class Domain, class T1, class T2, class VoxelFunc>
3262 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2)
3263 {
3264  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3265  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
3266 }
3267 
3268 // =============================================================================
3269 // 2 non-const images
3270 // =============================================================================
3271 
3272 // -----------------------------------------------------------------------------
3273 /**
3274  * ForEachVoxel body for voxel function of 2 non-const images
3275  */
3276 template <class T1, class T2, class VoxelFunc>
3277 struct BinaryForEachVoxelBody : public ForEachVoxelBody<VoxelFunc>
3278 {
3279  GenericImage<T1> &im1;
3280  GenericImage<T2> &im2;
3281 
3282  /// Constructor
3284  GenericImage<T2> &im2,
3285  VoxelFunc &vf)
3286  :
3287  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2)
3288  {}
3289 
3290  /// Copy constructor
3292  :
3293  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2)
3294  {}
3295 
3296  /// Split constructor
3298  :
3299  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2)
3300  {}
3301 
3302  /// Process entire image
3303  void operator ()(const ImageAttributes &attr) const
3304  {
3305  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3306  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3307 
3308  const int T = (attr._dt ? attr._t : 1);
3309 
3310  for (int l = 0; l < T; ++l)
3311  for (int k = 0; k < attr._z; ++k)
3312  for (int j = 0; j < attr._y; ++j)
3313  for (int i = 0; i < attr._x; ++i, ++p1, ++p2) {
3314  // const_cast such that voxel functions need only implement
3315  // non-const operator() which is required for parallel_reduce
3316  const_cast<BinaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, l, p1, p2);
3317  }
3318  }
3319 
3320  /// Process image region using linear index
3321  void operator ()(const blocked_range<int> &re) const
3322  {
3323  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3324  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3325 
3326  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1) {
3327  // const_cast such that voxel functions need only implement
3328  // non-const operator() which is required for parallel_reduce
3329  const_cast<BinaryForEachVoxelBody *>(this)->_VoxelFunc(im2, idx, p1, p2);
3330  }
3331  }
3332 
3333  /// Process 2D image region
3334  void operator ()(const blocked_range2d<int> &re) const
3335  {
3336  const int bi = re.cols().begin();
3337  const int bj = re.rows().begin();
3338  const int ei = re.cols().end();
3339  const int ej = re.rows().end();
3340 
3341  const int s1 = im2.GetX() - (ei - bi);
3342 
3343  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3344  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3345 
3346  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
3347  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
3348  // const_cast such that voxel functions need only implement
3349  // non-const operator() which is required for parallel_reduce
3350  const_cast<BinaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2);
3351  }
3352  }
3353 
3354  /// Process 3D image region
3355  void operator ()(const blocked_range3d<int> &re) const
3356  {
3357  const int bi = re.cols ().begin();
3358  const int bj = re.rows ().begin();
3359  const int bk = re.pages().begin();
3360  const int ei = re.cols ().end();
3361  const int ej = re.rows ().end();
3362  const int ek = re.pages().end();
3363 
3364  const int s1 = im2.GetX() - (ei - bi);
3365  const int s2 = (im2.GetY() - (ej - bj)) * im2.GetX();
3366 
3367  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3368  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3369 
3370  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2)
3371  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
3372  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
3373  // const_cast such that voxel functions need only implement
3374  // non-const operator() which is required for parallel_reduce
3375  const_cast<BinaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2);
3376  }
3377  }
3378 };
3379 
3380 // -----------------------------------------------------------------------------
3381 /**
3382  * ForEachVoxel body for inside and outside unary voxel function of 2 non-const images
3383  */
3384 template <class T1, class T2,
3385  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
3386  class Domain = ForEachVoxelDomain::Foreground>
3387 struct BinaryForEachVoxelIfBody : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
3388 {
3389  GenericImage<T1> &im1;
3390  GenericImage<T2> &im2;
3391 
3392  /// Constructor
3394  GenericImage<T2> &im2,
3395  VoxelFunc &vf, OutsideFunc &of)
3396  :
3397  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2)
3398  {}
3399 
3400  /// Copy constructor
3402  :
3403  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2)
3404  {}
3405 
3406  /// Split constructor
3408  :
3409  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2)
3410  {}
3411 
3412  /// Process entire image
3413  void operator ()(const ImageAttributes &attr) const
3414  {
3415  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3416  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3417 
3418  const int T = (attr._dt ? attr._t : 1);
3419 
3420  for (int l = 0; l < T; ++l)
3421  for (int k = 0; k < attr._z; ++k)
3422  for (int j = 0; j < attr._y; ++j)
3423  for (int i = 0; i < attr._x; ++i, ++p1, ++p2) {
3424  if (Domain::IsInside(im2, i, j, k, l, p2)) {
3425  // const_cast such that voxel functions need only implement
3426  // non-const operator() which is required for parallel_reduce
3427  const_cast<BinaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, l, p1, p2);
3428  } else const_cast<BinaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, l, p1, p2);
3429  }
3430  }
3431 
3432  /// Process image region using linear index
3433  void operator ()(const blocked_range<int> &re) const
3434  {
3435  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3436  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3437 
3438  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1) {
3439  if (Domain::IsInside(im2, idx, p2)) {
3440  // const_cast such that voxel functions need only implement
3441  // non-const operator() which is required for parallel_reduce
3442  const_cast<BinaryForEachVoxelIfBody *>(this)->_VoxelFunc (im2, idx, p1, p2);
3443  } else const_cast<BinaryForEachVoxelIfBody *>(this)->_OutsideFunc(im2, idx, p1, p2);
3444  }
3445  }
3446 
3447  /// Process 2D image region
3448  void operator ()(const blocked_range2d<int> &re) const
3449  {
3450  const int bi = re.cols().begin();
3451  const int bj = re.rows().begin();
3452  const int ei = re.cols().end();
3453  const int ej = re.rows().end();
3454 
3455  const int s1 = im2.GetX() - (ei - bi);
3456 
3457  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3458  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3459 
3460  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
3461  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
3462  if (Domain::IsInside(im2, i, j, this->_k, this->_l, p2)) {
3463  // const_cast such that voxel functions need only implement
3464  // non-const operator() which is required for parallel_reduce
3465  const_cast<BinaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2);
3466  } else const_cast<BinaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2);
3467  }
3468  }
3469 
3470  /// Process 3D image region
3471  void operator ()(const blocked_range3d<int> &re) const
3472  {
3473  const int bi = re.cols ().begin();
3474  const int bj = re.rows ().begin();
3475  const int bk = re.pages().begin();
3476  const int ei = re.cols ().end();
3477  const int ej = re.rows ().end();
3478  const int ek = re.pages().end();
3479 
3480  const int s1 = im2.GetX() - (ei - bi);
3481  const int s2 = (im2.GetY() - (ej - bj)) * im2.GetX();
3482 
3483  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3484  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3485 
3486  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2)
3487  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1)
3488  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1) {
3489  if (Domain::IsInside(im2, i, j, k, this->_l, p2)) {
3490  // const_cast such that voxel functions need only implement
3491  // non-const operator() which is required for parallel_reduce
3492  const_cast<BinaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2);
3493  } else const_cast<BinaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2);
3494  }
3495  }
3496 };
3497 
3498 // -----------------------------------------------------------------------------
3499 // ForEachVoxel
3500 // -----------------------------------------------------------------------------
3501 
3502 //
3503 // Image arguments by pointer
3504 //
3505 
3506 // -----------------------------------------------------------------------------
3507 template <class T1, class T2, class VoxelFunc>
3508 void ForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3509 {
3510  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
3511  blocked_range<int> re(0, im2->GetNumberOfVoxels());
3512  body(re);
3513  vf.join(body._VoxelFunc);
3514 }
3515 
3516 // -----------------------------------------------------------------------------
3517 template <class T1, class T2, class VoxelFunc>
3518 void ForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
3519 {
3520  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3521  ForEachScalar(*im1, *im2, vf);
3522 }
3523 
3524 // -----------------------------------------------------------------------------
3525 template <class T1, class T2, class VoxelFunc>
3526 void ForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3527 {
3528  if (im2->GetTSize()) {
3529  ForEachScalar(*im1, *im2, vf);
3530  } else {
3531  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
3532  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
3533  body(re);
3534  vf.join(body._VoxelFunc);
3535  }
3536 }
3537 
3538 // -----------------------------------------------------------------------------
3539 template <class T1, class T2, class VoxelFunc>
3540 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
3541 {
3542  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3543  ForEachVoxel(*im1, *im2, vf);
3544 }
3545 
3546 // -----------------------------------------------------------------------------
3547 template <class T1, class T2, class VoxelFunc>
3548 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3549 {
3550  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
3551  body(attr);
3552  vf.join(body._VoxelFunc);
3553 }
3554 
3555 // -----------------------------------------------------------------------------
3556 template <class T1, class T2, class VoxelFunc>
3557 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2)
3558 {
3559  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3560  ForEachVoxel(attr, *im1, *im2, vf);
3561 }
3562 
3563 // -----------------------------------------------------------------------------
3564 template <class T1, class T2, class VoxelFunc>
3565 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3566 {
3567  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
3568  body(re);
3569  vf.join(body._VoxelFunc);
3570 }
3571 
3572 // -----------------------------------------------------------------------------
3573 template <class T1, class T2, class VoxelFunc>
3574 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3575 {
3576  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3577  ForEachVoxel(re, *im1, *im2, vf);
3578 }
3579 
3580 // -----------------------------------------------------------------------------
3581 template <class T1, class T2, class VoxelFunc>
3582 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3583 {
3584  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
3585  body(re);
3586  vf.join(body._VoxelFunc);
3587 }
3588 
3589 // -----------------------------------------------------------------------------
3590 template <class T1, class T2, class VoxelFunc>
3591 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3592 {
3593  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3594  ForEachVoxel(re, *im1, *im2, vf);
3595 }
3596 
3597 // -----------------------------------------------------------------------------
3598 template <class T1, class T2, class VoxelFunc>
3599 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3600 {
3601  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
3602  body(re);
3603  vf.join(body._VoxelFunc);
3604 }
3605 
3606 // -----------------------------------------------------------------------------
3607 template <class T1, class T2, class VoxelFunc>
3608 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3609 {
3610  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3611  ForEachVoxel(re, *im1, *im2, vf);
3612 }
3613 
3614 //
3615 // Image arguments by reference
3616 //
3617 
3618 // -----------------------------------------------------------------------------
3619 template <class T1, class T2, class VoxelFunc>
3620 void ForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3621 {
3622  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
3624  body(re);
3625  vf.join(body._VoxelFunc);
3626 }
3627 
3628 // -----------------------------------------------------------------------------
3629 template <class T1, class T2, class VoxelFunc>
3630 void ForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
3631 {
3632  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3633  ForEachScalar(im1, im2, vf);
3634 }
3635 
3636 // -----------------------------------------------------------------------------
3637 template <class T1, class T2, class VoxelFunc>
3638 void ForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3639 {
3640  if (im2.GetTSize()) {
3641  ForEachScalar(im1, im2, vf);
3642  } else {
3643  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
3644  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
3645  body(re);
3646  vf.join(body._VoxelFunc);
3647  }
3648 }
3649 
3650 // -----------------------------------------------------------------------------
3651 template <class T1, class T2, class VoxelFunc>
3652 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
3653 {
3654  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3655  ForEachVoxel(im1, im2, vf);
3656 }
3657 
3658 // -----------------------------------------------------------------------------
3659 template <class T1, class T2, class VoxelFunc>
3660 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3661 {
3662  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
3663  body(attr);
3664  vf.join(body._VoxelFunc);
3665 }
3666 
3667 // -----------------------------------------------------------------------------
3668 template <class T1, class T2, class VoxelFunc>
3669 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2)
3670 {
3671  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3672  ForEachVoxel(attr, im1, im2, vf);
3673 }
3674 
3675 // -----------------------------------------------------------------------------
3676 template <class T1, class T2, class VoxelFunc>
3677 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3678 {
3679  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
3680  body(re);
3681  vf.join(body._VoxelFunc);
3682 }
3683 
3684 // -----------------------------------------------------------------------------
3685 template <class T1, class T2, class VoxelFunc>
3686 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
3687 {
3688  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3689  ForEachVoxel(re, im1, im2, vf);
3690 }
3691 
3692 // -----------------------------------------------------------------------------
3693 template <class T1, class T2, class VoxelFunc>
3694 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3695 {
3696  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
3697  body(re);
3698  vf.join(body._VoxelFunc);
3699 }
3700 
3701 // -----------------------------------------------------------------------------
3702 template <class T1, class T2, class VoxelFunc>
3703 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
3704 {
3705  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3706  ForEachVoxel(re, im1, im2, vf);
3707 }
3708 
3709 // -----------------------------------------------------------------------------
3710 template <class T1, class T2, class VoxelFunc>
3711 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3712 {
3713  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
3714  body(re);
3715  vf.join(body._VoxelFunc);
3716 }
3717 
3718 // -----------------------------------------------------------------------------
3719 template <class T1, class T2, class VoxelFunc>
3720 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
3721 {
3722  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3723  ForEachVoxel(re, im1, im2, vf);
3724 }
3725 
3726 // -----------------------------------------------------------------------------
3727 // ForEachVoxelIf
3728 // -----------------------------------------------------------------------------
3729 
3730 //
3731 // Image arguments by pointer
3732 //
3733 
3734 // -----------------------------------------------------------------------------
3735 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3736 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
3737 {
3739  blocked_range<int> re(0, im2->GetNumberOfVoxels());
3740  body(re);
3741  vf.join(body._VoxelFunc);
3742  of.join(body._OutsideFunc);
3743 }
3744 
3745 // -----------------------------------------------------------------------------
3746 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3747 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2)
3748 {
3749  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3750  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
3751 }
3752 
3753 // -----------------------------------------------------------------------------
3754 template <class Domain, class T1, class T2, class VoxelFunc>
3755 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3756 {
3758  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
3759 }
3760 
3761 // -----------------------------------------------------------------------------
3762 template <class Domain, class T1, class T2, class VoxelFunc>
3763 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
3764 {
3765  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3766  ForEachScalarIf<Domain>(*im1, *im2, vf);
3767 }
3768 
3769 // -----------------------------------------------------------------------------
3770 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3771 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
3772 {
3773  if (im2->GetTSize()) {
3774  ForEachScalarIf<Domain>(*im1, *im2, vf, of);
3775  } else {
3777  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
3778  body(re);
3779  vf.join(body._VoxelFunc);
3780  of.join(body._OutsideFunc);
3781  }
3782 }
3783 
3784 // -----------------------------------------------------------------------------
3785 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3786 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2)
3787 {
3788  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3789  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
3790 }
3791 
3792 // -----------------------------------------------------------------------------
3793 template <class Domain, class T1, class T2, class VoxelFunc>
3794 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3795 {
3797  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
3798 }
3799 
3800 // -----------------------------------------------------------------------------
3801 template <class Domain, class T1, class T2, class VoxelFunc>
3802 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
3803 {
3804  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3805  ForEachVoxelIf<Domain>(*im1, *im2, vf);
3806 }
3807 
3808 // -----------------------------------------------------------------------------
3809 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3810 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
3811 {
3813  body(attr);
3814  vf.join(body._VoxelFunc);
3815  of.join(body._OutsideFunc);
3816 }
3817 
3818 // -----------------------------------------------------------------------------
3819 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3820 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2)
3821 {
3822  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3823  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
3824 }
3825 
3826 // -----------------------------------------------------------------------------
3827 template <class Domain, class T1, class T2, class VoxelFunc>
3828 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3829 {
3831  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
3832 }
3833 
3834 // -----------------------------------------------------------------------------
3835 template <class Domain, class T1, class T2, class VoxelFunc>
3836 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2)
3837 {
3838  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3839  ForEachVoxelIf<Domain>(attr, *im1, *im2, vf);
3840 }
3841 
3842 // -----------------------------------------------------------------------------
3843 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3844 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
3845 {
3847  body(re);
3848  vf.join(body._VoxelFunc);
3849  of.join(body._OutsideFunc);
3850 }
3851 
3852 // -----------------------------------------------------------------------------
3853 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3854 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3855 {
3856  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3857  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
3858 }
3859 
3860 // -----------------------------------------------------------------------------
3861 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3862 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
3863 {
3865  body(re);
3866  vf.join(body._VoxelFunc);
3867  of.join(body._OutsideFunc);
3868 }
3869 
3870 // -----------------------------------------------------------------------------
3871 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3872 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3873 {
3874  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3875  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
3876 }
3877 
3878 // -----------------------------------------------------------------------------
3879 template <class Domain, class T1, class T2, class VoxelFunc>
3880 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3881 {
3883  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
3884 }
3885 
3886 // -----------------------------------------------------------------------------
3887 template <class Domain, class T1, class T2, class VoxelFunc>
3888 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3889 {
3890  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3891  ForEachVoxelIf<Domain>(re, *im1, *im2, vf);
3892 }
3893 
3894 // -----------------------------------------------------------------------------
3895 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3896 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
3897 {
3899  body(re);
3900  vf.join(body._VoxelFunc);
3901  of.join(body._OutsideFunc);
3902 }
3903 
3904 // -----------------------------------------------------------------------------
3905 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3906 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3907 {
3908  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3909  ForEachVoxelIf<Domain>(*im1, *im2, vf, of);
3910 }
3911 
3912 // -----------------------------------------------------------------------------
3913 template <class Domain, class T1, class T2, class VoxelFunc>
3914 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
3915 {
3917  ForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
3918 }
3919 
3920 // -----------------------------------------------------------------------------
3921 template <class Domain, class T1, class T2, class VoxelFunc>
3922 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
3923 {
3924  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3925  ForEachVoxelIf<Domain>(re, *im1, *im2, vf);
3926 }
3927 
3928 //
3929 // Image arguments by reference
3930 //
3931 
3932 // -----------------------------------------------------------------------------
3933 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3934 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3935 {
3938  body(re);
3939  vf.join(body._VoxelFunc);
3940  of.join(body._OutsideFunc);
3941 }
3942 
3943 // -----------------------------------------------------------------------------
3944 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3945 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2)
3946 {
3947  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3948  ForEachScalarIf<Domain>(im1, im2, vf, of);
3949 }
3950 
3951 // -----------------------------------------------------------------------------
3952 template <class Domain, class T1, class T2, class VoxelFunc>
3953 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3954 {
3956  ForEachScalarIf<Domain>(im1, im2, vf, of);
3957 }
3958 
3959 // -----------------------------------------------------------------------------
3960 template <class Domain, class T1, class T2, class VoxelFunc>
3961 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
3962 {
3963  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3964  ForEachScalarIf<Domain>(im1, im2, vf);
3965 }
3966 
3967 // -----------------------------------------------------------------------------
3968 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3969 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
3970 {
3971  if (im2.GetTSize()) {
3972  ForEachVoxelIf<Domain>(im1, im2, vf, of);
3973  } else {
3975  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
3976  body(re);
3977  vf.join(body._VoxelFunc);
3978  of.join(body._OutsideFunc);
3979  }
3980 }
3981 
3982 // -----------------------------------------------------------------------------
3983 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
3984 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2)
3985 {
3986  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
3987  ForEachVoxelIf<Domain>(im1, im2, vf, of);
3988 }
3989 
3990 // -----------------------------------------------------------------------------
3991 template <class Domain, class T1, class T2, class VoxelFunc>
3992 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
3993 {
3995  ForEachVoxelIf<Domain>(im1, im2, vf, of);
3996 }
3997 
3998 // -----------------------------------------------------------------------------
3999 template <class Domain, class T1, class T2, class VoxelFunc>
4000 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
4001 {
4002  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4003  ForEachVoxelIf<Domain>(im1, im2, vf);
4004 }
4005 
4006 // -----------------------------------------------------------------------------
4007 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4008 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4009 {
4011  body(attr);
4012  vf.join(body._VoxelFunc);
4013  of.join(body._OutsideFunc);
4014 }
4015 
4016 // -----------------------------------------------------------------------------
4017 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4018 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2)
4019 {
4020  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4021  ForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
4022 }
4023 
4024 // -----------------------------------------------------------------------------
4025 template <class Domain, class T1, class T2, class VoxelFunc>
4026 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4027 {
4029  ForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
4030 }
4031 
4032 // -----------------------------------------------------------------------------
4033 template <class Domain, class T1, class T2, class VoxelFunc>
4034 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2)
4035 {
4036  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4037  ForEachVoxelIf<Domain>(attr, im1, im2, vf);
4038 }
4039 
4040 // -----------------------------------------------------------------------------
4041 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4042 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4043 {
4045  body(re);
4046  vf.join(body._VoxelFunc);
4047  of.join(body._OutsideFunc);
4048 }
4049 
4050 // -----------------------------------------------------------------------------
4051 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4052 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4053 {
4054  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4055  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4056 }
4057 
4058 // -----------------------------------------------------------------------------
4059 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4060 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4061 {
4063  body(re);
4064  vf.join(body._VoxelFunc);
4065  of.join(body._OutsideFunc);
4066 }
4067 
4068 // -----------------------------------------------------------------------------
4069 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4070 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4071 {
4072  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4073  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4074 }
4075 
4076 // -----------------------------------------------------------------------------
4077 template <class Domain, class T1, class T2, class VoxelFunc>
4078 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4079 {
4081  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4082 }
4083 
4084 // -----------------------------------------------------------------------------
4085 template <class Domain, class T1, class T2, class VoxelFunc>
4086 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4087 {
4088  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4089  ForEachVoxelIf<Domain>(re, im1, im2, vf);
4090 }
4091 
4092 // -----------------------------------------------------------------------------
4093 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4094 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4095 {
4097  body(re);
4098  vf.join(body._VoxelFunc);
4099  of.join(body._OutsideFunc);
4100 }
4101 
4102 // -----------------------------------------------------------------------------
4103 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4104 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4105 {
4106  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4107  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4108 }
4109 
4110 // -----------------------------------------------------------------------------
4111 template <class Domain, class T1, class T2, class VoxelFunc>
4112 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4113 {
4115  ForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4116 }
4117 
4118 // -----------------------------------------------------------------------------
4119 template <class Domain, class T1, class T2, class VoxelFunc>
4120 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4121 {
4122  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4123  ForEachVoxelIf<Domain>(re, im1, im2, vf);
4124 }
4125 
4126 // -----------------------------------------------------------------------------
4127 // ParallelForEachVoxel
4128 // -----------------------------------------------------------------------------
4129 
4130 //
4131 // Image arguments by pointer
4132 //
4133 
4134 // -----------------------------------------------------------------------------
4135 template <class T1, class T2, class VoxelFunc>
4136 void ParallelForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4137 {
4138  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
4139  blocked_range<int> re(0, im2->GetNumberOfVoxels());
4140  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4141  else parallel_for (re, body);
4142 }
4143 
4144 // -----------------------------------------------------------------------------
4145 template <class T1, class T2, class VoxelFunc>
4146 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
4147 {
4148  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4149  ParallelForEachScalar(*im1, *im2, vf);
4150 }
4151 
4152 // -----------------------------------------------------------------------------
4153 template <class T1, class T2, class VoxelFunc>
4154 void ParallelForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4155 {
4156  if (im2->GetTSize()) {
4157  ParallelForEachScalar(*im1, *im2, vf);
4158  } else {
4159  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
4160  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
4161  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4162  else parallel_for (re, body);
4163  }
4164 }
4165 
4166 // -----------------------------------------------------------------------------
4167 template <class T1, class T2, class VoxelFunc>
4168 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
4169 {
4170  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4171  ParallelForEachVoxel(*im1, *im2, vf);
4172 }
4173 
4174 // -----------------------------------------------------------------------------
4175 template <class T1, class T2, class VoxelFunc>
4176 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4177 {
4178  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
4179  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4180  if (VoxelFunc::IsReduction()) {
4181  if (attr._dt) {
4182  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4183  } else {
4184  parallel_reduce(re, body);
4185  }
4186  vf.join(body._VoxelFunc);
4187  } else {
4188  if (attr._dt) {
4189  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4190  } else {
4191  parallel_for(re, body);
4192  }
4193  }
4194 }
4195 
4196 // -----------------------------------------------------------------------------
4197 template <class T1, class T2, class VoxelFunc>
4198 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2)
4199 {
4200  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4201  ParallelForEachVoxel(attr, *im1, *im2, vf);
4202 }
4203 
4204 // -----------------------------------------------------------------------------
4205 template <class T1, class T2, class VoxelFunc>
4206 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4207 {
4208  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
4209  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4210  else parallel_for (re, body);
4211 }
4212 
4213 // -----------------------------------------------------------------------------
4214 template <class T1, class T2, class VoxelFunc>
4215 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4216 {
4217  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4218  ParallelForEachVoxel(re, *im1, *im2, vf);
4219 }
4220 
4221 // -----------------------------------------------------------------------------
4222 template <class T1, class T2, class VoxelFunc>
4223 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4224 {
4225  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
4226  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4227  else parallel_for (re, body);
4228 }
4229 
4230 // -----------------------------------------------------------------------------
4231 template <class T1, class T2, class VoxelFunc>
4232 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4233 {
4234  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4235  ParallelForEachVoxel(re, *im1, *im2, vf);
4236 }
4237 
4238 // -----------------------------------------------------------------------------
4239 template <class T1, class T2, class VoxelFunc>
4240 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4241 {
4242  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(*im1, *im2, vf);
4243  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4244  else parallel_for (re, body);
4245 }
4246 
4247 // -----------------------------------------------------------------------------
4248 template <class T1, class T2, class VoxelFunc>
4249 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4250 {
4251  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4252  ParallelForEachVoxel(re, *im1, *im2, vf);
4253 }
4254 
4255 //
4256 // Image arguments by reference
4257 //
4258 
4259 // -----------------------------------------------------------------------------
4260 template <class T1, class T2, class VoxelFunc>
4261 void ParallelForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4262 {
4263  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
4265  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4266  else parallel_for (re, body);
4267 }
4268 
4269 // -----------------------------------------------------------------------------
4270 template <class T1, class T2, class VoxelFunc>
4271 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
4272 {
4273  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4274  ParallelForEachScalar(im1, im2, vf);
4275 }
4276 
4277 // -----------------------------------------------------------------------------
4278 template <class T1, class T2, class VoxelFunc>
4279 void ParallelForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4280 {
4281  if (im2.GetTSize()) {
4282  ParallelForEachScalar(im1, im2, vf);
4283  } else {
4284  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
4285  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
4286  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4287  else parallel_for (re, body);
4288  }
4289 }
4290 
4291 // -----------------------------------------------------------------------------
4292 template <class T1, class T2, class VoxelFunc>
4293 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
4294 {
4295  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4296  ParallelForEachVoxel(im1, im2, vf);
4297 }
4298 
4299 // -----------------------------------------------------------------------------
4300 template <class T1, class T2, class VoxelFunc>
4301 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4302 {
4303  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
4304  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4305  if (VoxelFunc::IsReduction()) {
4306  if (attr._dt) {
4307  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4308  } else {
4309  parallel_reduce(re, body);
4310  }
4311  vf.join(body._VoxelFunc);
4312  } else {
4313  if (attr._dt) {
4314  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4315  } else {
4316  parallel_for(re, body);
4317  }
4318  }
4319 }
4320 
4321 // -----------------------------------------------------------------------------
4322 template <class T1, class T2, class VoxelFunc>
4323 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2)
4324 {
4325  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4326  ParallelForEachVoxel(attr, im1, im2, vf);
4327 }
4328 
4329 // -----------------------------------------------------------------------------
4330 template <class T1, class T2, class VoxelFunc>
4331 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4332 {
4333  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, 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 VoxelFunc>
4340 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4341 {
4342  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4343  ParallelForEachVoxel(re, im1, im2, vf);
4344 }
4345 
4346 // -----------------------------------------------------------------------------
4347 template <class T1, class T2, class VoxelFunc>
4348 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4349 {
4350  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, 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 VoxelFunc>
4357 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4358 {
4359  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4360  ParallelForEachVoxel(re, im1, im2, vf);
4361 }
4362 
4363 // -----------------------------------------------------------------------------
4364 template <class T1, class T2, class VoxelFunc>
4365 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4366 {
4367  BinaryForEachVoxelBody<T1, T2, VoxelFunc> body(im1, im2, vf);
4368  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4369  else parallel_for (re, body);
4370 }
4371 
4372 // -----------------------------------------------------------------------------
4373 template <class T1, class T2, class VoxelFunc>
4374 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4375 {
4376  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4377  ParallelForEachVoxel(re, im1, im2, vf);
4378 }
4379 
4380 // -----------------------------------------------------------------------------
4381 // ParallelForEachVoxelIf
4382 // -----------------------------------------------------------------------------
4383 
4384 //
4385 // Image arguments by pointer
4386 //
4387 
4388 // -----------------------------------------------------------------------------
4389 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4390 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
4391 {
4393  blocked_range<int> re(0, im2->GetNumberOfVoxels());
4394  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4395  parallel_reduce(re, body);
4396  vf.join(body._VoxelFunc);
4397  of.join(body._OutsideFunc);
4398  } else {
4399  parallel_for(re, body);
4400  }
4401 }
4402 
4403 // -----------------------------------------------------------------------------
4404 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4405 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2)
4406 {
4407  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4408  ParallelForEachScalarIf<Domain>(*im1, *im2, vf, of);
4409 }
4410 
4411 // -----------------------------------------------------------------------------
4412 template <class Domain, class T1, class T2, class VoxelFunc>
4413 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4414 {
4416  ParallelForEachScalarIf<Domain>(*im1, *im2, vf, of);
4417 }
4418 
4419 // -----------------------------------------------------------------------------
4420 template <class Domain, class T1, class T2, class VoxelFunc>
4421 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
4422 {
4423  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4424  ParallelForEachScalarIf<Domain>(*im1, *im2, vf);
4425 }
4426 
4427 // -----------------------------------------------------------------------------
4428 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4429 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
4430 {
4431  if (im2->GetTSize()) {
4432  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
4433  } else {
4435  blocked_range<int> re(0, im2->GetNumberOfVoxels() / im2->GetT());
4436  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4437  parallel_reduce(re, body);
4438  vf.join(body._VoxelFunc);
4439  of.join(body._OutsideFunc);
4440  } else {
4441  parallel_for(re, body);
4442  }
4443  }
4444 }
4445 
4446 // -----------------------------------------------------------------------------
4447 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4448 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2)
4449 {
4450  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4451  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
4452 }
4453 
4454 // -----------------------------------------------------------------------------
4455 template <class Domain, class T1, class T2, class VoxelFunc>
4456 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4457 {
4459  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf, of);
4460 }
4461 
4462 // -----------------------------------------------------------------------------
4463 template <class Domain, class T1, class T2, class VoxelFunc>
4464 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2)
4465 {
4466  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4467  ParallelForEachVoxelIf<Domain>(*im1, *im2, vf);
4468 }
4469 
4470 // -----------------------------------------------------------------------------
4471 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4472 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
4473 {
4475  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4476  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4477  if (attr._dt) {
4478  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4479  } else {
4480  parallel_reduce(re, body);
4481  }
4482  vf.join(body._VoxelFunc);
4483  of.join(body._OutsideFunc);
4484  } else {
4485  if (attr._dt) {
4486  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4487  } else {
4488  parallel_for(re, body);
4489  }
4490  }
4491 }
4492 
4493 // -----------------------------------------------------------------------------
4494 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4495 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2)
4496 {
4497  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4498  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
4499 }
4500 
4501 // -----------------------------------------------------------------------------
4502 template <class Domain, class T1, class T2, class VoxelFunc>
4503 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4504 {
4506  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf, of);
4507 }
4508 
4509 // -----------------------------------------------------------------------------
4510 template <class Domain, class T1, class T2, class VoxelFunc>
4511 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2)
4512 {
4513  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4514  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, vf);
4515 }
4516 
4517 // -----------------------------------------------------------------------------
4518 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4519 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
4520 {
4522  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4523  parallel_reduce(re, body);
4524  vf.join(body._VoxelFunc);
4525  of.join(body._OutsideFunc);
4526  } else {
4527  parallel_for(re, body);
4528  }
4529 }
4530 
4531 // -----------------------------------------------------------------------------
4532 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4533 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4534 {
4535  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4536  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
4537 }
4538 
4539 // -----------------------------------------------------------------------------
4540 template <class Domain, class T1, class T2, class VoxelFunc>
4541 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4542 {
4544  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
4545 }
4546 
4547 // -----------------------------------------------------------------------------
4548 template <class Domain, class T1, class T2, class VoxelFunc>
4549 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4550 {
4551  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4552  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
4553 }
4554 
4555 // -----------------------------------------------------------------------------
4556 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4557 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
4558 {
4560  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4561  parallel_reduce(re, body);
4562  vf.join(body._VoxelFunc);
4563  of.join(body._OutsideFunc);
4564  } else {
4565  parallel_for(re, body);
4566  }
4567 }
4568 
4569 // -----------------------------------------------------------------------------
4570 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4571 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4572 {
4573  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4574  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
4575 }
4576 
4577 // -----------------------------------------------------------------------------
4578 template <class Domain, class T1, class T2, class VoxelFunc>
4579 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4580 {
4582  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
4583 }
4584 
4585 // -----------------------------------------------------------------------------
4586 template <class Domain, class T1, class T2, class VoxelFunc>
4587 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4588 {
4589  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4590  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
4591 }
4592 
4593 // -----------------------------------------------------------------------------
4594 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4595 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf, OutsideFunc &of)
4596 {
4598  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4599  parallel_reduce(re, body);
4600  vf.join(body._VoxelFunc);
4601  of.join(body._OutsideFunc);
4602  } else {
4603  parallel_for(re, body);
4604  }
4605 }
4606 
4607 // -----------------------------------------------------------------------------
4608 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4609 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4610 {
4611  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4612  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
4613 }
4614 
4615 // -----------------------------------------------------------------------------
4616 template <class Domain, class T1, class T2, class VoxelFunc>
4617 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, VoxelFunc &vf)
4618 {
4620  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf, of);
4621 }
4622 
4623 // -----------------------------------------------------------------------------
4624 template <class Domain, class T1, class T2, class VoxelFunc>
4625 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2)
4626 {
4627  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4628  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, vf);
4629 }
4630 
4631 //
4632 // Image arguments by reference
4633 //
4634 
4635 // -----------------------------------------------------------------------------
4636 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4637 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4638 {
4641  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4642  parallel_reduce(re, body);
4643  vf.join(body._VoxelFunc);
4644  of.join(body._OutsideFunc);
4645  } else {
4646  parallel_for(re, body);
4647  }
4648 }
4649 
4650 // -----------------------------------------------------------------------------
4651 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4652 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2)
4653 {
4654  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4655  ParallelForEachScalarIf<Domain>(im1, im2, vf, of);
4656 }
4657 
4658 // -----------------------------------------------------------------------------
4659 template <class Domain, class T1, class T2, class VoxelFunc>
4660 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4661 {
4663  ParallelForEachScalarIf<Domain>(im1, im2, vf, of);
4664 }
4665 
4666 // -----------------------------------------------------------------------------
4667 template <class Domain, class T1, class T2, class VoxelFunc>
4668 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
4669 {
4670  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4671  ParallelForEachScalarIf<Domain>(im1, im2, vf);
4672 }
4673 
4674 // -----------------------------------------------------------------------------
4675 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4676 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4677 {
4678  if (im2.GetTSize()) {
4679  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
4680  } else {
4682  blocked_range<int> re(0, im2.GetNumberOfVoxels() / im2.GetT());
4683  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4684  parallel_reduce(re, body);
4685  vf.join(body._VoxelFunc);
4686  of.join(body._OutsideFunc);
4687  } else {
4688  parallel_for(re, body);
4689  }
4690  }
4691 }
4692 
4693 // -----------------------------------------------------------------------------
4694 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4695 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2)
4696 {
4697  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4698  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
4699 }
4700 
4701 // -----------------------------------------------------------------------------
4702 template <class Domain, class T1, class T2, class VoxelFunc>
4703 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4704 {
4706  ParallelForEachVoxelIf<Domain>(im1, im2, vf, of);
4707 }
4708 
4709 // -----------------------------------------------------------------------------
4710 template <class Domain, class T1, class T2, class VoxelFunc>
4711 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2)
4712 {
4713  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4714  ParallelForEachVoxelIf<Domain>(im1, im2, vf);
4715 }
4716 
4717 // -----------------------------------------------------------------------------
4718 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4719 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4720 {
4722  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4723  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4724  if (attr._dt) {
4725  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4726  } else {
4727  parallel_reduce(re, body);
4728  }
4729  vf.join(body._VoxelFunc);
4730  of.join(body._OutsideFunc);
4731  } else {
4732  if (attr._dt) {
4733  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4734  } else {
4735  parallel_for(re, body);
4736  }
4737  }
4738 }
4739 
4740 // -----------------------------------------------------------------------------
4741 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4742 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2)
4743 {
4744  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4745  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
4746 }
4747 
4748 // -----------------------------------------------------------------------------
4749 template <class Domain, class T1, class T2, class VoxelFunc>
4750 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4751 {
4753  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf, of);
4754 }
4755 
4756 // -----------------------------------------------------------------------------
4757 template <class Domain, class T1, class T2, class VoxelFunc>
4758 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2)
4759 {
4760  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4761  ParallelForEachVoxelIf<Domain>(attr, im1, im2, vf);
4762 }
4763 
4764 // -----------------------------------------------------------------------------
4765 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4766 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4767 {
4769  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4770  parallel_reduce(re, body);
4771  vf.join(body._VoxelFunc);
4772  of.join(body._OutsideFunc);
4773  } else {
4774  parallel_for(re, body);
4775  }
4776 }
4777 
4778 // -----------------------------------------------------------------------------
4779 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4780 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4781 {
4782  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4783  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4784 }
4785 
4786 // -----------------------------------------------------------------------------
4787 template <class Domain, class T1, class T2, class VoxelFunc>
4788 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4789 {
4791  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4792 }
4793 
4794 // -----------------------------------------------------------------------------
4795 template <class Domain, class T1, class T2, class VoxelFunc>
4796 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4797 {
4798  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4799  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
4800 }
4801 
4802 // -----------------------------------------------------------------------------
4803 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4804 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4805 {
4807  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4808  parallel_reduce(re, body);
4809  vf.join(body._VoxelFunc);
4810  of.join(body._OutsideFunc);
4811  } else {
4812  parallel_for(re, body);
4813  }
4814 }
4815 
4816 // -----------------------------------------------------------------------------
4817 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4818 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4819 {
4820  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4821  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4822 }
4823 
4824 // -----------------------------------------------------------------------------
4825 template <class Domain, class T1, class T2, class VoxelFunc>
4826 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4827 {
4829  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4830 }
4831 
4832 // -----------------------------------------------------------------------------
4833 template <class Domain, class T1, class T2, class VoxelFunc>
4834 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4835 {
4836  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4837  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
4838 }
4839 
4840 // -----------------------------------------------------------------------------
4841 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4842 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf, OutsideFunc &of)
4843 {
4845  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4846  parallel_reduce(re, body);
4847  vf.join(body._VoxelFunc);
4848  of.join(body._OutsideFunc);
4849  } else {
4850  parallel_for(re, body);
4851  }
4852 }
4853 
4854 // -----------------------------------------------------------------------------
4855 template <class Domain, class T1, class T2, class VoxelFunc, class OutsideFunc>
4856 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4857 {
4858  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4859  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4860 }
4861 
4862 // -----------------------------------------------------------------------------
4863 template <class Domain, class T1, class T2, class VoxelFunc>
4864 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, VoxelFunc &vf)
4865 {
4867  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf, of);
4868 }
4869 
4870 // -----------------------------------------------------------------------------
4871 template <class Domain, class T1, class T2, class VoxelFunc>
4872 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2)
4873 {
4874  if (VoxelFunc::IsReduction()) _foreachbinaryvoxelfunction_must_not_be_reduction();
4875  ParallelForEachVoxelIf<Domain>(re, im1, im2, vf);
4876 }
4877 
4878 
4879 } // namespace mirtk
4880 
4881 #endif
double _dt
Voxel t-dimensions (in ms)
Dummy type used to distinguish split constructor from copy constructor.
Definition: Parallel.h:143
BinaryForEachVoxelIfBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, VoxelFunc &vf, OutsideFunc &of)
Constructor.
BinaryForEachVoxelIfBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, VoxelFunc &vf, OutsideFunc &of)
Constructor.
BinaryForEachVoxelBody_1Const(const BinaryForEachVoxelBody_1Const &o)
Copy constructor.
Two-dimensional range.
Definition: Parallel.h:168
bool IsEmpty() const
Whether image is uninitialized.
Definition: BaseImage.h:1283
int _y
Image y-dimension (in voxels)
BinaryForEachVoxelBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, VoxelFunc &vf)
Constructor.
One-dimensional range.
Definition: Parallel.h:155
BinaryForEachVoxelBody_Const(const BinaryForEachVoxelBody_Const &o)
Copy constructor.
BinaryForEachVoxelBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, VoxelFunc &vf)
Constructor.
VoxelFunc _VoxelFunc
Functor executed for each voxel.
BinaryForEachVoxelBody_Const(BinaryForEachVoxelBody_Const &o, split s)
Split constructor.
BinaryForEachVoxelIfBody(const BinaryForEachVoxelIfBody &o)
Copy constructor.
BinaryForEachVoxelIfBody_Const(BinaryForEachVoxelIfBody_Const &o, split s)
Split constructor.
Definition: IOConfig.h:41
VoxelType * GetPointerToVoxels(int=0, int=0, int=0, int=0)
Definition: GenericImage.h:849
int GetX() const
Returns the number of voxels in the x-direction.
Definition: BaseImage.h:904
BinaryForEachVoxelBody_1Const(BinaryForEachVoxelBody_1Const &o, split s)
Split constructor.
int _z
Image z-dimension (in voxels)
int _l
Indices for fixed dimensions.
BinaryForEachVoxelBody(const BinaryForEachVoxelBody &o)
Copy constructor.
int _t
Image t-dimension (in voxels)
int GetT() const
Returns the number of voxels in the t-direction.
Definition: BaseImage.h:922
void operator()(const ImageAttributes &attr) const
Process entire image.
int GetY() const
Returns the number of voxels in the y-direction.
Definition: BaseImage.h:910
Three-dimensional range.
Definition: Parallel.h:197
int GetNumberOfVoxels() const
Definition: BaseImage.h:1741
BinaryForEachVoxelIfBody_1Const(const BinaryForEachVoxelIfBody_1Const &o)
Copy constructor.
OutsideFunc _OutsideFunc
Functor executed for each background voxel.
BinaryForEachVoxelIfBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, VoxelFunc &vf, OutsideFunc &of)
Constructor.
double GetTSize() const
Returns the size of a voxel in the t-direction.
Definition: BaseImage.h:970
BinaryForEachVoxelBody(BinaryForEachVoxelBody &o, split s)
Split constructor.
BinaryForEachVoxelBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, 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
BinaryForEachVoxelIfBody(BinaryForEachVoxelIfBody &o, split s)
Split constructor.
void parallel_for(const Range &range, const Body &body)
parallel_for dummy template function which executes the body serially
Definition: Parallel.h:232
BinaryForEachVoxelIfBody_1Const(BinaryForEachVoxelIfBody_1Const &o, split s)
Split constructor.
BinaryForEachVoxelIfBody_Const(const BinaryForEachVoxelIfBody_Const &o)
Copy constructor.