Image Component Library (ICL)
SSEUtils.h
Go to the documentation of this file.
1 /********************************************************************
2 ** Image Component Library (ICL) **
3 ** **
4 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld **
5 ** Neuroinformatics Group **
6 ** Website: www.iclcv.org and **
7 ** http://opensource.cit-ec.de/projects/icl **
8 ** **
9 ** File : ICLUtils/src/ICLUtils/SSEUtils.h **
10 ** Module : ICLUtils **
11 ** Authors: Sergius Gaulik **
12 ** **
13 ** **
14 ** GNU LESSER GENERAL PUBLIC LICENSE **
15 ** This file may be used under the terms of the GNU Lesser General **
16 ** Public License version 3.0 as published by the **
17 ** **
18 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
19 ** included in the packaging of this file. Please review the **
20 ** following information to ensure the license requirements will **
21 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt **
22 ** **
23 ** The development of this software was supported by the **
24 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. **
25 ** The Excellence Cluster EXC 277 is a grant of the Deutsche **
26 ** Forschungsgemeinschaft (DFG) in the context of the German **
27 ** Excellence Initiative. **
28 ** **
29 ********************************************************************/
30 
31 #pragma once
32 
33 #include <ICLUtils/CompatMacros.h>
34 #include <ICLUtils/SSETypes.h>
35 
36 namespace icl{
37  namespace utils{
38 
39  #ifdef ICL_HAVE_SSE2
40 
41  // ++ rounding ++ //
42 
43  // possible modes:
44  // _MM_ROUND_NEAREST
45  // _MM_ROUND_DOWN
46  // _MM_ROUND_UP
47  // _MM_ROUND_TOWARD_ZERO
48 
49  static const unsigned int INITIAL_ROUNDING_MODE = _MM_GET_ROUNDING_MODE();
50  static unsigned int PREVIOUS_ROUNDING_MODE = INITIAL_ROUNDING_MODE;
51 
52  inline void sse_restore_initial_rounding_mode() {
53  _MM_SET_ROUNDING_MODE(INITIAL_ROUNDING_MODE);
54  }
55 
56  inline void sse_restore_previous_rounding_mode() {
57  const unsigned int mode = _MM_GET_ROUNDING_MODE();
58  _MM_SET_ROUNDING_MODE(PREVIOUS_ROUNDING_MODE);
59  PREVIOUS_ROUNDING_MODE = mode;
60  }
61 
62  inline void sse_set_rounding_mode(const unsigned int mode) {
63  PREVIOUS_ROUNDING_MODE = _MM_GET_ROUNDING_MODE();
64  _MM_SET_ROUNDING_MODE(mode);
65  }
66 
67  // -- rounding -- //
68 
69 
70  // ++ alignment ++ //
71 
72  template<class T>
73  inline int sse_is_16byte_aligned(const T *ptr) {
74  return !(((uintptr_t)ptr) & 15);
75  }
76 
77  template<class T>
78  inline int sse_is_not_16byte_aligned(const T *ptr) {
79  return (((uintptr_t)ptr) & 15);
80  }
81 
82  template<class T>
83  inline int sse_is_aligned(const T *ptr, const unsigned int bytes) {
84  return !(((uintptr_t)ptr) & (bytes-1));
85  }
86 
87  template<class T>
88  inline int sse_is_not_aligned(const T *ptr, const unsigned int bytes) {
89  return (((uintptr_t)ptr) & (bytes-1));
90  }
91 
92  // -- alignment -- //
93 
94 
95  // ++ conditions ++ //
96 
97  template<class T>
98  inline T sse_if(const T &vIf, const T &v0) {
99  T ret = (v0 & vIf);
100  return ret;
101  }
102 
103  template<class T>
104  inline T sse_ifelse(const T &vIf, const T &v0, const T &v1) {
105  T ret = (v0 & vIf);
106  ret += andnot(v1, vIf);
107  return ret;
108  }
109 
110  // -- conditions -- //
111 
112 
113  // ++ for-loops ++ //
114 
115  // the sse_for functions can be implemented compact in only one function
116  // using pointer-to-pointer, but it is slower than the current
117  // implementation of many versions
118 
119  template<class S, class D>
120  inline void sse_for(const S *src0,
121  D *dst0, D *dstEnd,
122  void (*subMethod)(const S*, D*),
123  void (*subSSEMethod)(const S*, D*),
124  long step) {
125  D *dstSSEEnd = dstEnd - (step - 1);
126 
127  for (; dst0<dstSSEEnd;) {
128  // convert 'rvalues' values at the same time
129  (*subSSEMethod)(src0, dst0);
130 
131  // increment pointers to the next values
132  src0 += step;
133  dst0 += step;
134  }
135 
136  for (; dst0<dstEnd; ++src0, ++dst0) {
137  // convert 1 value
138  (*subMethod)(src0, dst0);
139  }
140  }
141 
142  template<class S, class D>
143  inline void sse_for(const S *src0,
144  D *dst0, D *dst1, D *dstEnd,
145  void (*subMethod)(const S*, D*, D*),
146  void (*subSSEMethod)(const S*, D*, D*),
147  long step) {
148  D *dstSSEEnd = dstEnd - (step - 1);
149 
150  for (; dst0<dstSSEEnd;) {
151  // convert 'rvalues' values at the same time
152  (*subSSEMethod)(src0, dst0, dst1);
153 
154  // increment pointers to the next values
155  src0 += step;
156  dst0 += step;
157  dst1 += step;
158  }
159 
160  for (; dst0<dstEnd; ++src0, ++dst0, ++dst1) {
161  // convert 1 value
162  (*subMethod)(src0, dst0, dst1);
163  }
164  }
165 
166  template<class S, class D>
167  inline void sse_for(const S *src0,
168  D *dst0, D *dst1, D *dst2, D *dstEnd,
169  void (*subMethod)(const S*, D*, D*, D*),
170  void (*subSSEMethod)(const S*, D*, D*, D*),
171  long step) {
172  D *dstSSEEnd = dstEnd - (step - 1);
173 
174  for (; dst0<dstSSEEnd;) {
175  // convert 'rvalues' values at the same time
176  (*subSSEMethod)(src0, dst0, dst1, dst2);
177 
178  // increment pointers to the next values
179  src0 += step;
180  dst0 += step;
181  dst1 += step;
182  dst2 += step;
183  }
184 
185  for (; dst0<dstEnd; ++src0, ++dst0, ++dst1, ++dst2) {
186  // convert 1 value
187  (*subMethod)(src0, dst0, dst1, dst2);
188  }
189  }
190 
191  template<class S, class D>
192  inline void sse_for(const S *src0,
193  D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd,
194  void (*subMethod)(const S*, D*, D*, D*, D*),
195  void (*subSSEMethod)(const S*, D*, D*, D*, D*),
196  long step) {
197  D *dstSSEEnd = dstEnd - (step - 1);
198 
199  for (; dst0<dstSSEEnd;) {
200  // convert 'rvalues' values at the same time
201  (*subSSEMethod)(src0, dst0, dst1, dst2, dst3);
202 
203  // increment pointers to the next values
204  src0 += step;
205  dst0 += step;
206  dst1 += step;
207  dst2 += step;
208  dst3 += step;
209  }
210 
211  for (; dst0<dstEnd; ++src0, ++dst0, ++dst1, ++dst2, ++dst3) {
212  // convert 1 value
213  (*subMethod)(src0, dst0, dst1, dst2, dst3);
214  }
215  }
216 
217  template<class S, class D>
218  inline void sse_for(const S *src0, const S *src1,
219  D *dst0, D *dstEnd,
220  void (*subMethod)(const S*, const S*, D*),
221  void (*subSSEMethod)(const S*, const S*, D*),
222  long step) {
223  D *dstSSEEnd = dstEnd - (step - 1);
224 
225  for (; dst0<dstSSEEnd;) {
226  // convert 'rvalues' values at the same time
227  (*subSSEMethod)(src0, src1, dst0);
228 
229  // increment pointers to the next values
230  src0 += step;
231  src1 += step;
232  dst0 += step;
233  }
234 
235  for (; dst0<dstEnd; ++src0, ++src1, ++dst0) {
236  // convert 1 value
237  (*subMethod)(src0, src1, dst0);
238  }
239  }
240 
241  template<class S, class D>
242  inline void sse_for(const S *src0, const S *src1,
243  D *dst0, D *dst1, D *dstEnd,
244  void (*subMethod)(const S*, const S*, D*, D*),
245  void (*subSSEMethod)(const S*, const S*, D*, D*),
246  long step) {
247  D *dstSSEEnd = dstEnd - (step - 1);
248 
249  for (; dst0<dstSSEEnd;) {
250  // convert 'rvalues' values at the same time
251  (*subSSEMethod)(src0, src1, dst0, dst1);
252 
253  // increment pointers to the next values
254  src0 += step;
255  src1 += step;
256  dst0 += step;
257  dst1 += step;
258  }
259 
260  for (; dst0<dstEnd; ++src0, ++src1, ++dst0, ++dst1) {
261  // convert 1 value
262  (*subMethod)(src0, src1, dst0, dst1);
263  }
264  }
265 
266  template<class S, class D>
267  inline void sse_for(const S *src0, const S *src1,
268  D *dst0, D *dst1, D *dst2, D *dstEnd,
269  void (*subMethod)(const S*, const S*, D*, D*, D*),
270  void (*subSSEMethod)(const S*, const S*, D*, D*, D*),
271  long step) {
272  D *dstSSEEnd = dstEnd - (step - 1);
273 
274  for (; dst0<dstSSEEnd;) {
275  // convert 'rvalues' values at the same time
276  (*subSSEMethod)(src0, src1, dst0, dst1, dst2);
277 
278  // increment pointers to the next values
279  src0 += step;
280  src1 += step;
281  dst0 += step;
282  dst1 += step;
283  dst2 += step;
284  }
285 
286  for (; dst0<dstEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2) {
287  // convert 1 value
288  (*subMethod)(src0, src1, dst0, dst1, dst2);
289  }
290  }
291 
292  template<class S, class D>
293  inline void sse_for(const S *src0, const S *src1,
294  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
295  void (*subMethod)(const S*, const S*, D*, D*, D*, D*),
296  void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*),
297  long step) {
298  D *dstSSEEnd = dstEnd - (step - 1);
299 
300  for (; dst0<dstSSEEnd;) {
301  // convert 'rvalues' values at the same time
302  (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3);
303 
304  // increment pointers to the next values
305  src0 += step;
306  src1 += step;
307  dst0 += step;
308  dst1 += step;
309  dst2 += step;
310  dst3 += step;
311  }
312 
313  for (; dst0<dstEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2, ++dst3) {
314  // convert 1 value
315  (*subMethod)(src0, src1, dst0, dst1, dst2, dst3);
316  }
317  }
318 
319  template<class S, class D>
320  inline void sse_for(const S *src0, const S *src1, const S *src2,
321  D *dst0, D *dstEnd,
322  void (*subMethod)(const S*, const S*, const S*, D*),
323  void (*subSSEMethod)(const S*, const S*, const S*, D*),
324  long step) {
325  D *dstSSEEnd = dstEnd - (step - 1);
326 
327  for (; dst0<dstSSEEnd;) {
328  // convert 'rvalues' values at the same time
329  (*subSSEMethod)(src0, src1, src2, dst0);
330 
331  // increment pointers to the next values
332  src0 += step;
333  src1 += step;
334  src2 += step;
335  dst0 += step;
336  }
337 
338  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0) {
339  // convert 1 value
340  (*subMethod)(src0, src1, src2, dst0);
341  }
342  }
343 
344  template<class S, class D>
345  inline void sse_for(const S *src0, const S *src1, const S *src2,
346  D *dst0, D *dst1, D *dstEnd,
347  void (*subMethod)(const S*, const S*, const S*, D*, D*),
348  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*),
349  long step) {
350  D *dstSSEEnd = dstEnd - (step - 1);
351 
352  for (; dst0<dstSSEEnd;) {
353  // convert 'rvalues' values at the same time
354  (*subSSEMethod)(src0, src1, src2, dst0, dst1);
355 
356  // increment pointers to the next values
357  src0 += step;
358  src1 += step;
359  src2 += step;
360  dst0 += step;
361  dst1 += step;
362  }
363 
364  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1) {
365  // convert 1 value
366  (*subMethod)(src0, src1, src2, dst0, dst1);
367  }
368  }
369 
370  template<class S, class D>
371  inline void sse_for(const S *src0, const S *src1, const S *src2,
372  D *dst0, D *dst1, D *dst2, D *dstEnd,
373  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*),
374  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*),
375  long step) {
376  D *dstSSEEnd = dstEnd - (step - 1);
377 
378  for (; dst0<dstSSEEnd;) {
379  // convert 'rvalues' values at the same time
380  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2);
381 
382  // increment pointers to the next values
383  src0 += step;
384  src1 += step;
385  src2 += step;
386  dst0 += step;
387  dst1 += step;
388  dst2 += step;
389  }
390 
391  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2) {
392  // convert 1 value
393  (*subMethod)(src0, src1, src2, dst0, dst1, dst2);
394  }
395  }
396 
397  template<class S, class D>
398  inline void sse_for(const S *src0, const S *src1, const S *src2,
399  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
400  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
401  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
402  long step) {
403  D *dstSSEEnd = dstEnd - (step - 1);
404 
405  for (; dst0<dstSSEEnd;) {
406  // convert 'rvalues' values at the same time
407  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
408 
409  // increment pointers to the next values
410  src0 += step;
411  src1 += step;
412  src2 += step;
413  dst0 += step;
414  dst1 += step;
415  dst2 += step;
416  dst3 += step;
417  }
418 
419  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2, ++dst3) {
420  // convert 1 value
421  (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
422  }
423  }
424 
425  template<class S, class D>
426  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
427  D *dst0, D *dstEnd,
428  void (*subMethod)(const S*, const S*, const S*, const S*, D*),
429  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*),
430  long step) {
431  D *dstSSEEnd = dstEnd - (step - 1);
432 
433  for (; dst0<dstSSEEnd;) {
434  // convert 'rvalues' values at the same time
435  (*subSSEMethod)(src0, src1, src2, src3, dst0);
436 
437  // increment pointers to the next values
438  src0 += step;
439  src1 += step;
440  src2 += step;
441  src3 += step;
442  dst0 += step;
443  }
444 
445  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0) {
446  // convert 1 value
447  (*subMethod)(src0, src1, src2, src3, dst0);
448  }
449  }
450 
451  template<class S, class D>
452  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
453  D *dst0, D *dst1, D *dstEnd,
454  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*),
455  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*),
456  long step) {
457  D *dstSSEEnd = dstEnd - (step - 1);
458 
459  for (; dst0<dstSSEEnd;) {
460  // convert 'rvalues' values at the same time
461  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1);
462 
463  // increment pointers to the next values
464  src0 += step;
465  src1 += step;
466  src2 += step;
467  src3 += step;
468  dst0 += step;
469  dst1 += step;
470  }
471 
472  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1) {
473  // convert 1 value
474  (*subMethod)(src0, src1, src2, src3, dst0, dst1);
475  }
476  }
477 
478  template<class S, class D>
479  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
480  D *dst0, D *dst1, D *dst2, D *dstEnd,
481  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
482  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
483  long step) {
484  D *dstSSEEnd = dstEnd - (step - 1);
485 
486  for (; dst0<dstSSEEnd;) {
487  // convert 'rvalues' values at the same time
488  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
489 
490  // increment pointers to the next values
491  src0 += step;
492  src1 += step;
493  src2 += step;
494  src3 += step;
495  dst0 += step;
496  dst1 += step;
497  dst2 += step;
498  }
499 
500  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2) {
501  // convert 1 value
502  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
503  }
504  }
505 
506  template<class S, class D>
507  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
508  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
509  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
510  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
511  long step) {
512  D *dstSSEEnd = dstEnd - (step - 1);
513 
514  for (; dst0<dstSSEEnd;) {
515  // convert 'rvalues' values at the same time
516  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
517 
518  // increment pointers to the next values
519  src0 += step;
520  src1 += step;
521  src2 += step;
522  src3 += step;
523  dst0 += step;
524  dst1 += step;
525  dst2 += step;
526  dst3 += step;
527  }
528 
529  for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2, ++dst3) {
530  // convert 1 value
531  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
532  }
533  }
534 
535  // the sse_for functions can be implemented compact in only one function
536  // using pointer-to-pointer, but it is slower than the current
537  // implementation of many versions
538 
539  template<class S, class D>
540  inline void sse_for(const S *src0,
541  D *dst0, D *dstEnd,
542  void (*subMethod)(const S*, D*),
543  void (*subSSEMethod)(const S*, D*),
544  long srcStep, long dstStep) {
545  D *dstSSEEnd = dstEnd - (dstStep - 1);
546  long sStep, dStep;
547 
548  if (srcStep < dstStep) {
549  dStep = dstStep / srcStep;
550  sStep = 1;
551  } else {
552  sStep = srcStep / dstStep;
553  dStep = 1;
554  }
555 
556  for (; dst0<dstSSEEnd;) {
557  // convert 'rvalues' values at the same time
558  (*subSSEMethod)(src0, dst0);
559 
560  // increment pointers to the next values
561  src0 += srcStep;
562  dst0 += dstStep;
563  }
564 
565  for (; dst0<dstEnd; src0 += sStep, dst0 += dStep) {
566  // convert 1 value
567  (*subMethod)(src0, dst0);
568  }
569  }
570 
571  template<class S, class D>
572  inline void sse_for(const S *src0,
573  D *dst0, D *dst1, D *dstEnd,
574  void (*subMethod)(const S*, D*, D*),
575  void (*subSSEMethod)(const S*, D*, D*),
576  long srcStep, long dstStep) {
577  D *dstSSEEnd = dstEnd - (dstStep - 1);
578  long sStep, dStep;
579 
580  if (srcStep < dstStep) {
581  dStep = dstStep / srcStep;
582  sStep = 1;
583  } else {
584  sStep = srcStep / dstStep;
585  dStep = 1;
586  }
587 
588  for (; dst0<dstSSEEnd;) {
589  // convert 'rvalues' values at the same time
590  (*subSSEMethod)(src0, dst0, dst1);
591 
592  // increment pointers to the next values
593  src0 += srcStep;
594  dst0 += dstStep;
595  dst1 += dstStep;
596  }
597 
598  for (; dst0<dstEnd; src0 += sStep, dst0 += dStep, dst1 += dStep) {
599  // convert 1 value
600  (*subMethod)(src0, dst0, dst1);
601  }
602  }
603 
604  template<class S, class D>
605  inline void sse_for(const S *src0,
606  D *dst0, D *dst1, D *dst2, D *dstEnd,
607  void (*subMethod)(const S*, D*, D*, D*),
608  void (*subSSEMethod)(const S*, D*, D*, D*),
609  long srcStep, long dstStep) {
610  D *dstSSEEnd = dstEnd - (dstStep - 1);
611  long sStep, dStep;
612 
613  if (srcStep < dstStep) {
614  dStep = dstStep / srcStep;
615  sStep = 1;
616  } else {
617  sStep = srcStep / dstStep;
618  dStep = 1;
619  }
620 
621  for (; dst0<dstSSEEnd;) {
622  // convert 'rvalues' values at the same time
623  (*subSSEMethod)(src0, dst0, dst1, dst2);
624 
625  // increment pointers to the next values
626  src0 += srcStep;
627  dst0 += dstStep;
628  dst1 += dstStep;
629  dst2 += dstStep;
630  }
631 
632  for (; dst0<dstEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
633  // convert 1 value
634  (*subMethod)(src0, dst0, dst1, dst2);
635  }
636  }
637 
638  template<class S, class D>
639  inline void sse_for(const S *src0,
640  D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd,
641  void (*subMethod)(const S*, D*, D*, D*, D*),
642  void (*subSSEMethod)(const S*, D*, D*, D*, D*),
643  long srcStep, long dstStep) {
644  D *dstSSEEnd = dstEnd - (dstStep - 1);
645  long sStep, dStep;
646 
647  if (srcStep < dstStep) {
648  dStep = dstStep / srcStep;
649  sStep = 1;
650  } else {
651  sStep = srcStep / dstStep;
652  dStep = 1;
653  }
654 
655  for (; dst0<dstSSEEnd;) {
656  // convert 'rvalues' values at the same time
657  (*subSSEMethod)(src0, dst0, dst1, dst2, dst3);
658 
659  // increment pointers to the next values
660  src0 += srcStep;
661  dst0 += dstStep;
662  dst1 += dstStep;
663  dst2 += dstStep;
664  dst3 += dstStep;
665  }
666 
667  for (; dst0<dstEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
668  // convert 1 value
669  (*subMethod)(src0, dst0, dst1, dst2, dst3);
670  }
671  }
672 
673  template<class S, class D>
674  inline void sse_for(const S *src0, const S *src1,
675  D *dst0, D *dstEnd,
676  void (*subMethod)(const S*, const S*, D*),
677  void (*subSSEMethod)(const S*, const S*, D*),
678  long srcStep, long dstStep) {
679  D *dstSSEEnd = dstEnd - (dstStep - 1);
680  long sStep, dStep;
681 
682  if (srcStep < dstStep) {
683  dStep = dstStep / srcStep;
684  sStep = 1;
685  } else {
686  sStep = srcStep / dstStep;
687  dStep = 1;
688  }
689 
690  for (; dst0<dstSSEEnd;) {
691  // convert 'rvalues' values at the same time
692  (*subSSEMethod)(src0, src1, dst0);
693 
694  // increment pointers to the next values
695  src0 += srcStep;
696  src1 += srcStep;
697  dst0 += dstStep;
698  }
699 
700  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep) {
701  // convert 1 value
702  (*subMethod)(src0, src1, dst0);
703  }
704  }
705 
706  template<class S, class D>
707  inline void sse_for(const S *src0, const S *src1,
708  D *dst0, D *dst1, D *dstEnd,
709  void (*subMethod)(const S*, const S*, D*, D*),
710  void (*subSSEMethod)(const S*, const S*, D*, D*),
711  long srcStep, long dstStep) {
712  D *dstSSEEnd = dstEnd - (dstStep - 1);
713  long sStep, dStep;
714 
715  if (srcStep < dstStep) {
716  dStep = dstStep / srcStep;
717  sStep = 1;
718  } else {
719  sStep = srcStep / dstStep;
720  dStep = 1;
721  }
722 
723  for (; dst0<dstSSEEnd;) {
724  // convert 'rvalues' values at the same time
725  (*subSSEMethod)(src0, src1, dst0, dst1);
726 
727  // increment pointers to the next values
728  src0 += srcStep;
729  src1 += srcStep;
730  dst0 += dstStep;
731  dst1 += dstStep;
732  }
733 
734  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep) {
735  // convert 1 value
736  (*subMethod)(src0, src1, dst0, dst1);
737  }
738  }
739 
740  template<class S, class D>
741  inline void sse_for(const S *src0, const S *src1,
742  D *dst0, D *dst1, D *dst2, D *dstEnd,
743  void (*subMethod)(const S*, const S*, D*, D*, D*),
744  void (*subSSEMethod)(const S*, const S*, D*, D*, D*),
745  long srcStep, long dstStep) {
746  D *dstSSEEnd = dstEnd - (dstStep - 1);
747  long sStep, dStep;
748 
749  if (srcStep < dstStep) {
750  dStep = dstStep / srcStep;
751  sStep = 1;
752  } else {
753  sStep = srcStep / dstStep;
754  dStep = 1;
755  }
756 
757  for (; dst0<dstSSEEnd;) {
758  // convert 'rvalues' values at the same time
759  (*subSSEMethod)(src0, src1, dst0, dst1, dst2);
760 
761  // increment pointers to the next values
762  src0 += srcStep;
763  src1 += srcStep;
764  dst0 += dstStep;
765  dst1 += dstStep;
766  dst2 += dstStep;
767  }
768 
769  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
770  // convert 1 value
771  (*subMethod)(src0, src1, dst0, dst1, dst2);
772  }
773  }
774 
775  template<class S, class D>
776  inline void sse_for(const S *src0, const S *src1,
777  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
778  void (*subMethod)(const S*, const S*, D*, D*, D*, D*),
779  void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*),
780  long srcStep, long dstStep) {
781  D *dstSSEEnd = dstEnd - (dstStep - 1);
782  long sStep, dStep;
783 
784  if (srcStep < dstStep) {
785  dStep = dstStep / srcStep;
786  sStep = 1;
787  } else {
788  sStep = srcStep / dstStep;
789  dStep = 1;
790  }
791 
792  for (; dst0<dstSSEEnd;) {
793  // convert 'rvalues' values at the same time
794  (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3);
795 
796  // increment pointers to the next values
797  src0 += srcStep;
798  src1 += srcStep;
799  dst0 += dstStep;
800  dst1 += dstStep;
801  dst2 += dstStep;
802  dst3 += dstStep;
803  }
804 
805  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
806  // convert 1 value
807  (*subMethod)(src0, src1, dst0, dst1, dst2, dst3);
808  }
809  }
810 
811  template<class S, class D>
812  inline void sse_for(const S *src0, const S *src1, const S *src2,
813  D *dst0, D *dstEnd,
814  void (*subMethod)(const S*, const S*, const S*, D*),
815  void (*subSSEMethod)(const S*, const S*, const S*, D*),
816  long srcStep, long dstStep) {
817  D *dstSSEEnd = dstEnd - (dstStep - 1);
818  long sStep, dStep;
819 
820  if (srcStep < dstStep) {
821  dStep = dstStep / srcStep;
822  sStep = 1;
823  } else {
824  sStep = srcStep / dstStep;
825  dStep = 1;
826  }
827 
828  for (; dst0<dstSSEEnd;) {
829  // convert 'rvalues' values at the same time
830  (*subSSEMethod)(src0, src1, src2, dst0);
831 
832  // increment pointers to the next values
833  src0 += srcStep;
834  src1 += srcStep;
835  src2 += srcStep;
836  dst0 += dstStep;
837  }
838 
839  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep) {
840  // convert 1 value
841  (*subMethod)(src0, src1, src2, dst0);
842  }
843  }
844 
845  template<class S, class D>
846  inline void sse_for(const S *src0, const S *src1, const S *src2,
847  D *dst0, D *dst1, D *dstEnd,
848  void (*subMethod)(const S*, const S*, const S*, D*, D*),
849  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*),
850  long srcStep, long dstStep) {
851  D *dstSSEEnd = dstEnd - (dstStep - 1);
852  long sStep, dStep;
853 
854  if (srcStep < dstStep) {
855  dStep = dstStep / srcStep;
856  sStep = 1;
857  } else {
858  sStep = srcStep / dstStep;
859  dStep = 1;
860  }
861 
862  for (; dst0<dstSSEEnd;) {
863  // convert 'rvalues' values at the same time
864  (*subSSEMethod)(src0, src1, src2, dst0, dst1);
865 
866  // increment pointers to the next values
867  src0 += srcStep;
868  src1 += srcStep;
869  src2 += srcStep;
870  dst0 += dstStep;
871  dst1 += dstStep;
872  }
873 
874  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep) {
875  // convert 1 value
876  (*subMethod)(src0, src1, src2, dst0, dst1);
877  }
878  }
879 
880  template<class S, class D>
881  inline void sse_for(const S *src0, const S *src1, const S *src2,
882  D *dst0, D *dst1, D *dst2, D *dstEnd,
883  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*),
884  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*),
885  long srcStep, long dstStep) {
886  D *dstSSEEnd = dstEnd - (dstStep - 1);
887  long sStep, dStep;
888 
889  if (srcStep < dstStep) {
890  dStep = dstStep / srcStep;
891  sStep = 1;
892  } else {
893  sStep = srcStep / dstStep;
894  dStep = 1;
895  }
896 
897  for (; dst0<dstSSEEnd;) {
898  // convert 'rvalues' values at the same time
899  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2);
900 
901  // increment pointers to the next values
902  src0 += srcStep;
903  src1 += srcStep;
904  src2 += srcStep;
905  dst0 += dstStep;
906  dst1 += dstStep;
907  dst2 += dstStep;
908  }
909 
910  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
911  // convert 1 value
912  (*subMethod)(src0, src1, src2, dst0, dst1, dst2);
913  }
914  }
915 
916  template<class S, class D>
917  inline void sse_for(const S *src0, const S *src1, const S *src2,
918  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
919  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
920  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
921  long srcStep, long dstStep) {
922  D *dstSSEEnd = dstEnd - (dstStep - 1);
923  long sStep, dStep;
924 
925  if (srcStep < dstStep) {
926  dStep = dstStep / srcStep;
927  sStep = 1;
928  } else {
929  sStep = srcStep / dstStep;
930  dStep = 1;
931  }
932 
933  for (; dst0<dstSSEEnd;) {
934  // convert 'rvalues' values at the same time
935  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
936 
937  // increment pointers to the next values
938  src0 += srcStep;
939  src1 += srcStep;
940  src2 += srcStep;
941  dst0 += dstStep;
942  dst1 += dstStep;
943  dst2 += dstStep;
944  dst3 += dstStep;
945  }
946 
947  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
948  // convert 1 value
949  (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
950  }
951  }
952 
953  template<class S, class D>
954  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
955  D *dst0, D *dstEnd,
956  void (*subMethod)(const S*, const S*, const S*, const S*, D*),
957  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*),
958  long srcStep, long dstStep) {
959  D *dstSSEEnd = dstEnd - (dstStep - 1);
960  long sStep, dStep;
961 
962  if (srcStep < dstStep) {
963  dStep = dstStep / srcStep;
964  sStep = 1;
965  } else {
966  sStep = srcStep / dstStep;
967  dStep = 1;
968  }
969 
970  for (; dst0<dstSSEEnd;) {
971  // convert 'rvalues' values at the same time
972  (*subSSEMethod)(src0, src1, src2, src3, dst0);
973 
974  // increment pointers to the next values
975  src0 += srcStep;
976  src1 += srcStep;
977  src2 += srcStep;
978  src3 += srcStep;
979  dst0 += dstStep;
980  }
981 
982  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep) {
983  // convert 1 value
984  (*subMethod)(src0, src1, src2, src3, dst0);
985  }
986  }
987 
988  template<class S, class D>
989  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
990  D *dst0, D *dst1, D *dstEnd,
991  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*),
992  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*),
993  long srcStep, long dstStep) {
994  D *dstSSEEnd = dstEnd - (dstStep - 1);
995  long sStep, dStep;
996 
997  if (srcStep < dstStep) {
998  dStep = dstStep / srcStep;
999  sStep = 1;
1000  } else {
1001  sStep = srcStep / dstStep;
1002  dStep = 1;
1003  }
1004 
1005  for (; dst0<dstSSEEnd;) {
1006  // convert 'rvalues' values at the same time
1007  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1);
1008 
1009  // increment pointers to the next values
1010  src0 += srcStep;
1011  src1 += srcStep;
1012  src2 += srcStep;
1013  src3 += srcStep;
1014  dst0 += dstStep;
1015  dst1 += dstStep;
1016  }
1017 
1018  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep) {
1019  // convert 1 value
1020  (*subMethod)(src0, src1, src2, src3, dst0, dst1);
1021  }
1022  }
1023 
1024  template<class S, class D>
1025  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
1026  D *dst0, D *dst1, D *dst2, D *dstEnd,
1027  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
1028  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
1029  long srcStep, long dstStep) {
1030  D *dstSSEEnd = dstEnd - (dstStep - 1);
1031  long sStep, dStep;
1032 
1033  if (srcStep < dstStep) {
1034  dStep = dstStep / srcStep;
1035  sStep = 1;
1036  } else {
1037  sStep = srcStep / dstStep;
1038  dStep = 1;
1039  }
1040 
1041  for (; dst0<dstSSEEnd;) {
1042  // convert 'rvalues' values at the same time
1043  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
1044 
1045  // increment pointers to the next values
1046  src0 += srcStep;
1047  src1 += srcStep;
1048  src2 += srcStep;
1049  src3 += srcStep;
1050  dst0 += dstStep;
1051  dst1 += dstStep;
1052  dst2 += dstStep;
1053  }
1054 
1055  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
1056  // convert 1 value
1057  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
1058  }
1059  }
1060 
1061  template<class S, class D>
1062  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
1063  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
1064  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
1065  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
1066  long srcStep, long dstStep) {
1067  D *dstSSEEnd = dstEnd - (dstStep - 1);
1068  long sStep, dStep;
1069 
1070  if (srcStep < dstStep) {
1071  dStep = dstStep / srcStep;
1072  sStep = 1;
1073  } else {
1074  sStep = srcStep / dstStep;
1075  dStep = 1;
1076  }
1077 
1078  for (; dst0<dstSSEEnd;) {
1079  // convert 'rvalues' values at the same time
1080  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
1081 
1082  // increment pointers to the next values
1083  src0 += srcStep;
1084  src1 += srcStep;
1085  src2 += srcStep;
1086  src3 += srcStep;
1087  dst0 += dstStep;
1088  dst1 += dstStep;
1089  dst2 += dstStep;
1090  dst3 += dstStep;
1091  }
1092 
1093  for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
1094  // convert 1 value
1095  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
1096  }
1097  }
1098 
1099  // -- for-loops -- //
1100 
1101 
1102  // ++ for-loops with ROI ++ //
1103 
1104  // the sse_for functions can be implemented compact in only one function
1105  // using pointer-to-pointer, but it is slower than the current
1106  // implementation of many versions
1107 
1108  template<class S, class D>
1109  inline void sse_for(const S *src0,
1110  D *dst0, D *dstEnd,
1111  long srcWidth, long dstWidth, long lineWidth,
1112  void (*subMethod)(const S*, D*),
1113  void (*subSSEMethod)(const S*, D*),
1114  long step) {
1115  D *dstLEnd = dst0 + lineWidth;
1116  D *dstSSEEnd = dstLEnd - (step - 1);
1117  long srcOffset = srcWidth - lineWidth;
1118  long dstOffset = dstWidth - lineWidth;
1119 
1120  for (; dst0<dstEnd;) {
1121  if (dst0<dstSSEEnd) {
1122  // convert 'rvalues' values at the same time
1123  (*subSSEMethod)(src0, dst0);
1124 
1125  // increment pointers to the next values
1126  src0 += step;
1127  dst0 += step;
1128  } else {
1129  for (; dst0<dstLEnd; ++src0, ++dst0) {
1130  // convert 1 value
1131  (*subMethod)(src0, dst0);
1132  }
1133 
1134  // move all pointers to the next line
1135  dstLEnd += dstWidth;
1136  dstSSEEnd += dstWidth;
1137  src0 += srcOffset;
1138  dst0 += dstOffset;
1139  }
1140  }
1141  }
1142 
1143  template<class S, class D>
1144  inline void sse_for(const S *src0,
1145  D *dst0, D *dst1, D *dstEnd,
1146  long srcWidth, long dstWidth, long lineWidth,
1147  void (*subMethod)(const S*, D*, D*),
1148  void (*subSSEMethod)(const S*, D*, D*),
1149  long step) {
1150  D *dstLEnd = dst0 + lineWidth;
1151  D *dstSSEEnd = dstLEnd - (step - 1);
1152  long srcOffset = srcWidth - lineWidth;
1153  long dstOffset = dstWidth - lineWidth;
1154 
1155  for (; dst0<dstEnd;) {
1156  if (dst0<dstSSEEnd) {
1157  // convert 'rvalues' values at the same time
1158  (*subSSEMethod)(src0, dst0, dst1);
1159 
1160  // increment pointers to the next values
1161  src0 += step;
1162  dst0 += step;
1163  dst1 += step;
1164  } else {
1165  for (; dst0<dstLEnd; ++src0, ++dst0, ++dst1) {
1166  // convert 1 value
1167  (*subMethod)(src0, dst0, dst1);
1168  }
1169 
1170  // move all pointers to the next line
1171  dstLEnd += dstWidth;
1172  dstSSEEnd += dstWidth;
1173  src0 += srcOffset;
1174  dst0 += dstOffset;
1175  dst1 += dstOffset;
1176  }
1177  }
1178  }
1179 
1180  template<class S, class D>
1181  inline void sse_for(const S *src0,
1182  D *dst0, D *dst1, D *dst2, D *dstEnd,
1183  long srcWidth, long dstWidth, long lineWidth,
1184  void (*subMethod)(const S*, D*, D*, D*),
1185  void (*subSSEMethod)(const S*, D*, D*, D*),
1186  long step) {
1187  D *dstLEnd = dst0 + lineWidth;
1188  D *dstSSEEnd = dstLEnd - (step - 1);
1189  long srcOffset = srcWidth - lineWidth;
1190  long dstOffset = dstWidth - lineWidth;
1191 
1192  for (; dst0<dstEnd;) {
1193  if (dst0<dstSSEEnd) {
1194  // convert 'rvalues' values at the same time
1195  (*subSSEMethod)(src0, dst0, dst1, dst2);
1196 
1197  // increment pointers to the next values
1198  src0 += step;
1199  dst0 += step;
1200  dst1 += step;
1201  dst2 += step;
1202  } else {
1203  for (; dst0<dstLEnd; ++src0, ++dst0, ++dst1, ++dst2) {
1204  // convert 1 value
1205  (*subMethod)(src0, dst0, dst1, dst2);
1206  }
1207 
1208  // move all pointers to the next line
1209  dstLEnd += dstWidth;
1210  dstSSEEnd += dstWidth;
1211  src0 += srcOffset;
1212  dst0 += dstOffset;
1213  dst1 += dstOffset;
1214  dst2 += dstOffset;
1215  }
1216  }
1217  }
1218 
1219  template<class S, class D>
1220  inline void sse_for(const S *src0,
1221  D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd,
1222  long srcWidth, long dstWidth, long lineWidth,
1223  void (*subMethod)(const S*, D*, D*, D*, D*),
1224  void (*subSSEMethod)(const S*, D*, D*, D*, D*),
1225  long step) {
1226  D *dstLEnd = dst0 + lineWidth;
1227  D *dstSSEEnd = dstLEnd - (step - 1);
1228  long srcOffset = srcWidth - lineWidth;
1229  long dstOffset = dstWidth - lineWidth;
1230 
1231  for (; dst0<dstEnd;) {
1232  if (dst0<dstSSEEnd) {
1233  // convert 'rvalues' values at the same time
1234  (*subSSEMethod)(src0, dst0, dst1, dst2, dst3);
1235 
1236  // increment pointers to the next values
1237  src0 += step;
1238  dst0 += step;
1239  dst1 += step;
1240  dst2 += step;
1241  dst3 += step;
1242  } else {
1243  for (; dst0<dstLEnd; ++src0, ++dst0, ++dst1, ++dst2, ++dst3) {
1244  // convert 1 value
1245  (*subMethod)(src0, dst0, dst1, dst2, dst3);
1246  }
1247 
1248  // move all pointers to the next line
1249  dstLEnd += dstWidth;
1250  dstSSEEnd += dstWidth;
1251  src0 += srcOffset;
1252  dst0 += dstOffset;
1253  dst1 += dstOffset;
1254  dst2 += dstOffset;
1255  dst3 += dstOffset;
1256  }
1257  }
1258  }
1259 
1260  template<class S, class D>
1261  inline void sse_for(const S *src0, const S *src1,
1262  D *dst0, D *dst1, D *dstEnd,
1263  long srcWidth, long dstWidth, long lineWidth,
1264  void (*subMethod)(const S*, const S*, D*, D*),
1265  void (*subSSEMethod)(const S*, const S*, D*, D*),
1266  long step) {
1267  D *dstLEnd = dst0 + lineWidth;
1268  D *dstSSEEnd = dstLEnd - (step - 1);
1269  long srcOffset = srcWidth - lineWidth;
1270  long dstOffset = dstWidth - lineWidth;
1271 
1272  for (; dst0<dstEnd;) {
1273  if (dst0<dstSSEEnd) {
1274  // convert 'rvalues' values at the same time
1275  (*subSSEMethod)(src0, src1, dst0, dst1);
1276 
1277  // increment pointers to the next values
1278  src0 += step;
1279  src1 += step;
1280  dst0 += step;
1281  dst1 += step;
1282  } else {
1283  for (; dst0<dstLEnd; ++src0, ++src1, ++dst0, ++dst1) {
1284  // convert 1 value
1285  (*subMethod)(src0, src1, dst0, dst1);
1286  }
1287 
1288  // move all pointers to the next line
1289  dstLEnd += dstWidth;
1290  dstSSEEnd += dstWidth;
1291  src0 += srcOffset;
1292  src1 += srcOffset;
1293  dst0 += dstOffset;
1294  dst1 += dstOffset;
1295  }
1296  }
1297  }
1298 
1299  template<class S, class D>
1300  inline void sse_for(const S *src0, const S *src1,
1301  D *dst0, D *dst1, D *dst2, D *dstEnd,
1302  long srcWidth, long dstWidth, long lineWidth,
1303  void (*subMethod)(const S*, const S*, D*, D*, D*),
1304  void (*subSSEMethod)(const S*, const S*, D*, D*, D*),
1305  long step) {
1306  D *dstLEnd = dst0 + lineWidth;
1307  D *dstSSEEnd = dstLEnd - (step - 1);
1308  long srcOffset = srcWidth - lineWidth;
1309  long dstOffset = dstWidth - lineWidth;
1310 
1311  for (; dst0<dstEnd;) {
1312  if (dst0<dstSSEEnd) {
1313  // convert 'rvalues' values at the same time
1314  (*subSSEMethod)(src0, src1, dst0, dst1, dst2);
1315 
1316  // increment pointers to the next values
1317  src0 += step;
1318  src1 += step;
1319  dst0 += step;
1320  dst1 += step;
1321  dst2 += step;
1322  } else {
1323  for (; dst0<dstLEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2) {
1324  // convert 1 value
1325  (*subMethod)(src0, src1, dst0, dst1, dst2);
1326  }
1327 
1328  // move all pointers to the next line
1329  dstLEnd += dstWidth;
1330  dstSSEEnd += dstWidth;
1331  src0 += srcOffset;
1332  src1 += srcOffset;
1333  dst0 += dstOffset;
1334  dst1 += dstOffset;
1335  dst2 += dstOffset;
1336  }
1337  }
1338  }
1339 
1340  template<class S, class D>
1341  inline void sse_for(const S *src0, const S *src1,
1342  D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd,
1343  long srcWidth, long dstWidth, long lineWidth,
1344  void (*subMethod)(const S*, const S*, D*, D*, D*, D*),
1345  void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*),
1346  long step) {
1347  D *dstLEnd = dst0 + lineWidth;
1348  D *dstSSEEnd = dstLEnd - (step - 1);
1349  long srcOffset = srcWidth - lineWidth;
1350  long dstOffset = dstWidth - lineWidth;
1351 
1352  for (; dst0<dstEnd;) {
1353  if (dst0<dstSSEEnd) {
1354  // convert 'rvalues' values at the same time
1355  (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3);
1356 
1357  // increment pointers to the next values
1358  src0 += step;
1359  src1 += step;
1360  dst0 += step;
1361  dst1 += step;
1362  dst2 += step;
1363  dst3 += step;
1364  } else {
1365  for (; dst0<dstLEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2, ++dst3) {
1366  // convert 1 value
1367  (*subMethod)(src0, src1, dst0, dst1, dst2, dst3);
1368  }
1369 
1370  // move all pointers to the next line
1371  dstLEnd += dstWidth;
1372  dstSSEEnd += dstWidth;
1373  src0 += srcOffset;
1374  src1 += srcOffset;
1375  dst0 += dstOffset;
1376  dst1 += dstOffset;
1377  dst2 += dstOffset;
1378  dst3 += dstOffset;
1379  }
1380  }
1381  }
1382 
1383  template<class S, class D>
1384  inline void sse_for(const S *src0, const S *src1, const S *src2,
1385  D *dst0, D *dstEnd,
1386  long srcWidth, long dstWidth, long lineWidth,
1387  void (*subMethod)(const S*, const S*, const S*, D*),
1388  void (*subSSEMethod)(const S*, const S*, const S*, D*),
1389  long step) {
1390  D *dstLEnd = dst0 + lineWidth;
1391  D *dstSSEEnd = dstLEnd - (step - 1);
1392  long srcOffset = srcWidth - lineWidth;
1393  long dstOffset = dstWidth - lineWidth;
1394 
1395  for (; dst0<dstEnd;) {
1396  if (dst0<dstSSEEnd) {
1397  // convert 'rvalues' values at the same time
1398  (*subSSEMethod)(src0, src1, src2, dst0);
1399 
1400  // increment pointers to the next values
1401  src0 += step;
1402  src1 += step;
1403  src2 += step;
1404  dst0 += step;
1405  } else {
1406  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0) {
1407  // convert 1 value
1408  (*subMethod)(src0, src1, src2, dst0);
1409  }
1410 
1411  // move all pointers to the next line
1412  dstLEnd += dstWidth;
1413  dstSSEEnd += dstWidth;
1414  src0 += srcOffset;
1415  src1 += srcOffset;
1416  src2 += srcOffset;
1417  dst0 += dstOffset;
1418  }
1419  }
1420  }
1421 
1422  template<class S, class D>
1423  inline void sse_for(const S *src0, const S *src1, const S *src2,
1424  D *dst0, D *dst1, D *dstEnd,
1425  long srcWidth, long dstWidth, long lineWidth,
1426  void (*subMethod)(const S*, const S*, const S*, D*, D*),
1427  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*),
1428  long step) {
1429  D *dstLEnd = dst0 + lineWidth;
1430  D *dstSSEEnd = dstLEnd - (step - 1);
1431  long srcOffset = srcWidth - lineWidth;
1432  long dstOffset = dstWidth - lineWidth;
1433 
1434  for (; dst0<dstEnd;) {
1435  if (dst0<dstSSEEnd) {
1436  // convert 'rvalues' values at the same time
1437  (*subSSEMethod)(src0, src1, src2, dst0, dst1);
1438 
1439  // increment pointers to the next values
1440  src0 += step;
1441  src1 += step;
1442  src2 += step;
1443  dst0 += step;
1444  dst1 += step;
1445  } else {
1446  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1) {
1447  // convert 1 value
1448  (*subMethod)(src0, src1, src2, dst0, dst1);
1449  }
1450 
1451  // move all pointers to the next line
1452  dstLEnd += dstWidth;
1453  dstSSEEnd += dstWidth;
1454  src0 += srcOffset;
1455  src1 += srcOffset;
1456  src2 += srcOffset;
1457  dst0 += dstOffset;
1458  dst1 += dstOffset;
1459  }
1460  }
1461  }
1462 
1463  template<class S, class D>
1464  inline void sse_for(const S *src0, const S *src1, const S *src2,
1465  D *dst0, D *dst1, D *dst2, D *dstEnd,
1466  long srcWidth, long dstWidth, long lineWidth,
1467  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*),
1468  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*),
1469  long step) {
1470  D *dstLEnd = dst0 + lineWidth;
1471  D *dstSSEEnd = dstLEnd - (step - 1);
1472  long srcOffset = srcWidth - lineWidth;
1473  long dstOffset = dstWidth - lineWidth;
1474 
1475  for (; dst0<dstEnd;) {
1476  if (dst0<dstSSEEnd) {
1477  // convert 'rvalues' values at the same time
1478  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2);
1479 
1480  // increment pointers to the next values
1481  src0 += step;
1482  src1 += step;
1483  src2 += step;
1484  dst0 += step;
1485  dst1 += step;
1486  dst2 += step;
1487  } else {
1488  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2) {
1489  // convert 1 value
1490  (*subMethod)(src0, src1, src2, dst0, dst1, dst2);
1491  }
1492 
1493  // move all pointers to the next line
1494  dstLEnd += dstWidth;
1495  dstSSEEnd += dstWidth;
1496  src0 += srcOffset;
1497  src1 += srcOffset;
1498  src2 += srcOffset;
1499  dst0 += dstOffset;
1500  dst1 += dstOffset;
1501  dst2 += dstOffset;
1502  }
1503  }
1504  }
1505 
1506  template<class S, class D>
1507  inline void sse_for(const S *src0, const S *src1, const S *src2,
1508  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
1509  long srcWidth, long dstWidth, long lineWidth,
1510  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
1511  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
1512  long step) {
1513  D *dstLEnd = dst0 + lineWidth;
1514  D *dstSSEEnd = dstLEnd - (step - 1);
1515  long srcOffset = srcWidth - lineWidth;
1516  long dstOffset = dstWidth - lineWidth;
1517 
1518  for (; dst0<dstEnd;) {
1519  if (dst0<dstSSEEnd) {
1520  // convert 'rvalues' values at the same time
1521  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
1522 
1523  // increment pointers to the next values
1524  src0 += step;
1525  src1 += step;
1526  src2 += step;
1527  dst0 += step;
1528  dst1 += step;
1529  dst2 += step;
1530  dst3 += step;
1531  } else {
1532  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2, ++dst3) {
1533  // convert 1 value
1534  (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
1535  }
1536 
1537  // move all pointers to the next line
1538  dstLEnd += dstWidth;
1539  dstSSEEnd += dstWidth;
1540  src0 += srcOffset;
1541  src1 += srcOffset;
1542  src2 += srcOffset;
1543  dst0 += dstOffset;
1544  dst1 += dstOffset;
1545  dst2 += dstOffset;
1546  dst3 += dstOffset;
1547  }
1548  }
1549  }
1550 
1551  template<class S, class D>
1552  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
1553  D *dst0, D *dstEnd,
1554  long srcWidth, long dstWidth, long lineWidth,
1555  void (*subMethod)(const S*, const S*, const S*, const S*, D*),
1556  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*),
1557  long step) {
1558  D *dstLEnd = dst0 + lineWidth;
1559  D *dstSSEEnd = dstLEnd - (step - 1);
1560  long srcOffset = srcWidth - lineWidth;
1561  long dstOffset = dstWidth - lineWidth;
1562 
1563  for (; dst0<dstEnd;) {
1564  if (dst0<dstSSEEnd) {
1565  // convert 'rvalues' values at the same time
1566  (*subSSEMethod)(src0, src1, src2, src3, dst0);
1567 
1568  // increment pointers to the next values
1569  src0 += step;
1570  src1 += step;
1571  src2 += step;
1572  src3 += step;
1573  dst0 += step;
1574  } else {
1575  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0) {
1576  // convert 1 value
1577  (*subMethod)(src0, src1, src2, src3, dst0);
1578  }
1579 
1580  // move all pointers to the next line
1581  dstLEnd += dstWidth;
1582  dstSSEEnd += dstWidth;
1583  src0 += srcOffset;
1584  src1 += srcOffset;
1585  src2 += srcOffset;
1586  src3 += srcOffset;
1587  dst0 += dstOffset;
1588  }
1589  }
1590  }
1591 
1592  template<class S, class D>
1593  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
1594  D *dst0, D *dst1, D *dstEnd,
1595  long srcWidth, long dstWidth, long lineWidth,
1596  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*),
1597  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*),
1598  long step) {
1599  D *dstLEnd = dst0 + lineWidth;
1600  D *dstSSEEnd = dstLEnd - (step - 1);
1601  long srcOffset = srcWidth - lineWidth;
1602  long dstOffset = dstWidth - lineWidth;
1603 
1604  for (; dst0<dstEnd;) {
1605  if (dst0<dstSSEEnd) {
1606  // convert 'rvalues' values at the same time
1607  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1);
1608 
1609  // increment pointers to the next values
1610  src0 += step;
1611  src1 += step;
1612  src2 += step;
1613  src3 += step;
1614  dst0 += step;
1615  dst1 += step;
1616  } else {
1617  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1) {
1618  // convert 1 value
1619  (*subMethod)(src0, src1, src2, src3, dst0, dst1);
1620  }
1621 
1622  // move all pointers to the next line
1623  dstLEnd += dstWidth;
1624  dstSSEEnd += dstWidth;
1625  src0 += srcOffset;
1626  src1 += srcOffset;
1627  src2 += srcOffset;
1628  src3 += srcOffset;
1629  dst0 += dstOffset;
1630  dst1 += dstOffset;
1631  }
1632  }
1633  }
1634 
1635  template<class S, class D>
1636  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
1637  D *dst0, D *dst1, D *dst2, D *dstEnd,
1638  long srcWidth, long dstWidth, long lineWidth,
1639  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
1640  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
1641  long step) {
1642  D *dstLEnd = dst0 + lineWidth;
1643  D *dstSSEEnd = dstLEnd - (step - 1);
1644  long srcOffset = srcWidth - lineWidth;
1645  long dstOffset = dstWidth - lineWidth;
1646 
1647  for (; dst0<dstEnd;) {
1648  if (dst0<dstSSEEnd) {
1649  // convert 'rvalues' values at the same time
1650  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
1651 
1652  // increment pointers to the next values
1653  src0 += step;
1654  src1 += step;
1655  src2 += step;
1656  src3 += step;
1657  dst0 += step;
1658  dst1 += step;
1659  dst2 += step;
1660  } else {
1661  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2) {
1662  // convert 1 value
1663  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
1664  }
1665 
1666  // move all pointers to the next line
1667  dstLEnd += dstWidth;
1668  dstSSEEnd += dstWidth;
1669  src0 += srcOffset;
1670  src1 += srcOffset;
1671  src2 += srcOffset;
1672  src3 += srcOffset;
1673  dst0 += dstOffset;
1674  dst1 += dstOffset;
1675  dst2 += dstOffset;
1676  }
1677  }
1678  }
1679 
1680  template<class S, class D>
1681  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
1682  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
1683  long srcWidth, long dstWidth, long lineWidth,
1684  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
1685  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
1686  long step) {
1687  D *dstLEnd = dst0 + lineWidth;
1688  D *dstSSEEnd = dstLEnd - (step - 1);
1689  long srcOffset = srcWidth - lineWidth;
1690  long dstOffset = dstWidth - lineWidth;
1691 
1692  for (; dst0<dstEnd;) {
1693  if (dst0<dstSSEEnd) {
1694  // convert 'rvalues' values at the same time
1695  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
1696 
1697  // increment pointers to the next values
1698  src0 += step;
1699  src1 += step;
1700  src2 += step;
1701  src3 += step;
1702  dst0 += step;
1703  dst1 += step;
1704  dst2 += step;
1705  dst3 += step;
1706  } else {
1707  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2, ++dst3) {
1708  // convert 1 value
1709  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
1710  }
1711 
1712  // move all pointers to the next line
1713  dstLEnd += dstWidth;
1714  dstSSEEnd += dstWidth;
1715  src0 += srcOffset;
1716  src1 += srcOffset;
1717  src2 += srcOffset;
1718  src3 += srcOffset;
1719  dst0 += dstOffset;
1720  dst1 += dstOffset;
1721  dst2 += dstOffset;
1722  dst3 += dstOffset;
1723  }
1724  }
1725  }
1726 
1727  template<class S, class D>
1728  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, const S *src4,
1729  D *dst0, D *dstEnd,
1730  long srcWidth, long dstWidth, long lineWidth,
1731  void (*subMethod)(const S*, const S*, const S*, const S*, const S*, D*),
1732  void (*subSSEMethod)(const S*, const S*, const S*, const S*, const S*, D*),
1733  long step) {
1734  D *dstLEnd = dst0 + lineWidth;
1735  D *dstSSEEnd = dstLEnd - (step - 1);
1736  long srcOffset = srcWidth - lineWidth;
1737  long dstOffset = dstWidth - lineWidth;
1738 
1739  for (; dst0<dstEnd;) {
1740  if (dst0<dstSSEEnd) {
1741  // convert 'rvalues' values at the same time
1742  (*subSSEMethod)(src0, src1, src2, src3, src4, dst0);
1743 
1744  // increment pointers to the next values
1745  src0 += step;
1746  src1 += step;
1747  src2 += step;
1748  src3 += step;
1749  src4 += step;
1750  dst0 += step;
1751  } else {
1752  for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++src4, ++dst0) {
1753  // convert 1 value
1754  (*subMethod)(src0, src1, src2, src3, src4, dst0);
1755  }
1756 
1757  // move all pointers to the next line
1758  dstLEnd += dstWidth;
1759  dstSSEEnd += dstWidth;
1760  src0 += srcOffset;
1761  src1 += srcOffset;
1762  src2 += srcOffset;
1763  src3 += srcOffset;
1764  src4 += srcOffset;
1765  dst0 += dstOffset;
1766  }
1767  }
1768  }
1769 
1770  // the sse_for functions can be implemented compact in only one function
1771  // using pointer-to-pointer, but it is slower than the current
1772  // implementation of many versions
1773 
1774  template<class S, class D>
1775  inline void sse_for(const S *src0,
1776  D *dst0, D *dstEnd,
1777  long srcWidth, long dstWidth, long lineWidth,
1778  void (*subMethod)(const S*, D*),
1779  void (*subSSEMethod)(const S*, D*),
1780  long srcStep, long dstStep) {
1781  D *dstLEnd = dst0 + lineWidth;
1782  D *dstSSEEnd = dstLEnd - (dstStep - 1);
1783  long srcOffset = srcWidth - lineWidth;
1784  long dstOffset = dstWidth - lineWidth;
1785  long sStep, dStep;
1786 
1787  if (srcStep < dstStep) {
1788  dStep = dstStep / srcStep;
1789  sStep = 1;
1790  } else {
1791  sStep = srcStep / dstStep;
1792  dStep = 1;
1793  }
1794 
1795  for (; dst0<dstEnd;) {
1796  if (dst0<dstSSEEnd) {
1797  // convert 'rvalues' values at the same time
1798  (*subSSEMethod)(src0, dst0);
1799 
1800  // increment pointers to the next values
1801  src0 += srcStep;
1802  dst0 += dstStep;
1803  } else {
1804  for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep) {
1805  // convert 1 value
1806  (*subMethod)(src0, dst0);
1807  }
1808 
1809  // move all pointers to the next line
1810  dstLEnd += dstWidth;
1811  dstSSEEnd += dstWidth;
1812  src0 += srcOffset;
1813  dst0 += dstOffset;
1814  }
1815  }
1816  }
1817 
1818  template<class S, class D>
1819  inline void sse_for(const S *src0,
1820  D *dst0, D *dst1, D *dstEnd,
1821  long srcWidth, long dstWidth, long lineWidth,
1822  void (*subMethod)(const S*, D*, D*),
1823  void (*subSSEMethod)(const S*, D*, D*),
1824  long srcStep, long dstStep) {
1825  D *dstLEnd = dst0 + lineWidth;
1826  D *dstSSEEnd = dstLEnd - (dstStep - 1);
1827  long srcOffset = srcWidth - lineWidth;
1828  long dstOffset = dstWidth - lineWidth;
1829  long sStep, dStep;
1830 
1831  if (srcStep < dstStep) {
1832  dStep = dstStep / srcStep;
1833  sStep = 1;
1834  } else {
1835  sStep = srcStep / dstStep;
1836  dStep = 1;
1837  }
1838 
1839  for (; dst0<dstEnd;) {
1840  if (dst0<dstSSEEnd) {
1841  // convert 'rvalues' values at the same time
1842  (*subSSEMethod)(src0, dst0, dst1);
1843 
1844  // increment pointers to the next values
1845  src0 += srcStep;
1846  dst0 += dstStep;
1847  dst1 += dstStep;
1848  } else {
1849  for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep, dst1 += dStep) {
1850  // convert 1 value
1851  (*subMethod)(src0, dst0, dst1);
1852  }
1853 
1854  // move all pointers to the next line
1855  dstLEnd += dstWidth;
1856  dstSSEEnd += dstWidth;
1857  src0 += srcOffset;
1858  dst0 += dstOffset;
1859  dst1 += dstOffset;
1860  }
1861  }
1862  }
1863 
1864  template<class S, class D>
1865  inline void sse_for(const S *src0,
1866  D *dst0, D *dst1, D *dst2, D *dstEnd,
1867  long srcWidth, long dstWidth, long lineWidth,
1868  void (*subMethod)(const S*, D*, D*, D*),
1869  void (*subSSEMethod)(const S*, D*, D*, D*),
1870  long srcStep, long dstStep) {
1871  D *dstLEnd = dst0 + lineWidth;
1872  D *dstSSEEnd = dstLEnd - (dstStep - 1);
1873  long srcOffset = srcWidth - lineWidth;
1874  long dstOffset = dstWidth - lineWidth;
1875  long sStep, dStep;
1876 
1877  if (srcStep < dstStep) {
1878  dStep = dstStep / srcStep;
1879  sStep = 1;
1880  } else {
1881  sStep = srcStep / dstStep;
1882  dStep = 1;
1883  }
1884 
1885  for (; dst0<dstEnd;) {
1886  if (dst0<dstSSEEnd) {
1887  // convert 'rvalues' values at the same time
1888  (*subSSEMethod)(src0, dst0, dst1, dst2);
1889 
1890  // increment pointers to the next values
1891  src0 += srcStep;
1892  dst0 += dstStep;
1893  dst1 += dstStep;
1894  dst2 += dstStep;
1895  } else {
1896  for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
1897  // convert 1 value
1898  (*subMethod)(src0, dst0, dst1, dst2);
1899  }
1900 
1901  // move all pointers to the next line
1902  dstLEnd += dstWidth;
1903  dstSSEEnd += dstWidth;
1904  src0 += srcOffset;
1905  dst0 += dstOffset;
1906  dst1 += dstOffset;
1907  dst2 += dstOffset;
1908  }
1909  }
1910  }
1911 
1912  template<class S, class D>
1913  inline void sse_for(const S *src0,
1914  D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd,
1915  long srcWidth, long dstWidth, long lineWidth,
1916  void (*subMethod)(const S*, D*, D*, D*, D*),
1917  void (*subSSEMethod)(const S*, D*, D*, D*, D*),
1918  long srcStep, long dstStep) {
1919  D *dstLEnd = dst0 + lineWidth;
1920  D *dstSSEEnd = dstLEnd - (dstStep - 1);
1921  long srcOffset = srcWidth - lineWidth;
1922  long dstOffset = dstWidth - lineWidth;
1923  long sStep, dStep;
1924 
1925  if (srcStep < dstStep) {
1926  dStep = dstStep / srcStep;
1927  sStep = 1;
1928  } else {
1929  sStep = srcStep / dstStep;
1930  dStep = 1;
1931  }
1932 
1933  for (; dst0<dstEnd;) {
1934  if (dst0<dstSSEEnd) {
1935  // convert 'rvalues' values at the same time
1936  (*subSSEMethod)(src0, dst0, dst1, dst2, dst3);
1937 
1938  // increment pointers to the next values
1939  src0 += srcStep;
1940  dst0 += dstStep;
1941  dst1 += dstStep;
1942  dst2 += dstStep;
1943  dst3 += dstStep;
1944  } else {
1945  for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
1946  // convert 1 value
1947  (*subMethod)(src0, dst0, dst1, dst2, dst3);
1948  }
1949 
1950  // move all pointers to the next line
1951  dstLEnd += dstWidth;
1952  dstSSEEnd += dstWidth;
1953  src0 += srcOffset;
1954  dst0 += dstOffset;
1955  dst1 += dstOffset;
1956  dst2 += dstOffset;
1957  dst3 += dstOffset;
1958  }
1959  }
1960  }
1961 
1962  template<class S, class D>
1963  inline void sse_for(const S *src0, const S *src1,
1964  D *dst0, D *dst1, D *dstEnd,
1965  long srcWidth, long dstWidth, long lineWidth,
1966  void (*subMethod)(const S*, const S*, D*, D*),
1967  void (*subSSEMethod)(const S*, const S*, D*, D*),
1968  long srcStep, long dstStep) {
1969  D *dstLEnd = dst0 + lineWidth;
1970  D *dstSSEEnd = dstLEnd - (dstStep - 1);
1971  long srcOffset = srcWidth - lineWidth;
1972  long dstOffset = dstWidth - lineWidth;
1973  long sStep, dStep;
1974 
1975  if (srcStep < dstStep) {
1976  dStep = dstStep / srcStep;
1977  sStep = 1;
1978  } else {
1979  sStep = srcStep / dstStep;
1980  dStep = 1;
1981  }
1982 
1983  for (; dst0<dstEnd;) {
1984  if (dst0<dstSSEEnd) {
1985  // convert 'rvalues' values at the same time
1986  (*subSSEMethod)(src0, src1, dst0, dst1);
1987 
1988  // increment pointers to the next values
1989  src0 += srcStep;
1990  src1 += srcStep;
1991  dst0 += dstStep;
1992  dst1 += dstStep;
1993  } else {
1994  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep) {
1995  // convert 1 value
1996  (*subMethod)(src0, src1, dst0, dst1);
1997  }
1998 
1999  // move all pointers to the next line
2000  dstLEnd += dstWidth;
2001  dstSSEEnd += dstWidth;
2002  src0 += srcOffset;
2003  src1 += srcOffset;
2004  dst0 += dstOffset;
2005  dst1 += dstOffset;
2006  }
2007  }
2008  }
2009 
2010  template<class S, class D>
2011  inline void sse_for(const S *src0, const S *src1,
2012  D *dst0, D *dst1, D *dst2, D *dstEnd,
2013  long srcWidth, long dstWidth, long lineWidth,
2014  void (*subMethod)(const S*, const S*, D*, D*, D*),
2015  void (*subSSEMethod)(const S*, const S*, D*, D*, D*),
2016  long srcStep, long dstStep) {
2017  D *dstLEnd = dst0 + lineWidth;
2018  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2019  long srcOffset = srcWidth - lineWidth;
2020  long dstOffset = dstWidth - lineWidth;
2021  long sStep, dStep;
2022 
2023  if (srcStep < dstStep) {
2024  dStep = dstStep / srcStep;
2025  sStep = 1;
2026  } else {
2027  sStep = srcStep / dstStep;
2028  dStep = 1;
2029  }
2030 
2031  for (; dst0<dstEnd;) {
2032  if (dst0<dstSSEEnd) {
2033  // convert 'rvalues' values at the same time
2034  (*subSSEMethod)(src0, src1, dst0, dst1, dst2);
2035 
2036  // increment pointers to the next values
2037  src0 += srcStep;
2038  src1 += srcStep;
2039  dst0 += dstStep;
2040  dst1 += dstStep;
2041  dst2 += dstStep;
2042  } else {
2043  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
2044  // convert 1 value
2045  (*subMethod)(src0, src1, dst0, dst1, dst2);
2046  }
2047 
2048  // move all pointers to the next line
2049  dstLEnd += dstWidth;
2050  dstSSEEnd += dstWidth;
2051  src0 += srcOffset;
2052  src1 += srcOffset;
2053  dst0 += dstOffset;
2054  dst1 += dstOffset;
2055  dst2 += dstOffset;
2056  }
2057  }
2058  }
2059 
2060  template<class S, class D>
2061  inline void sse_for(const S *src0, const S *src1,
2062  D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd,
2063  long srcWidth, long dstWidth, long lineWidth,
2064  void (*subMethod)(const S*, const S*, D*, D*, D*, D*),
2065  void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*),
2066  long srcStep, long dstStep) {
2067  D *dstLEnd = dst0 + lineWidth;
2068  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2069  long srcOffset = srcWidth - lineWidth;
2070  long dstOffset = dstWidth - lineWidth;
2071  long sStep, dStep;
2072 
2073  if (srcStep < dstStep) {
2074  dStep = dstStep / srcStep;
2075  sStep = 1;
2076  } else {
2077  sStep = srcStep / dstStep;
2078  dStep = 1;
2079  }
2080 
2081  for (; dst0<dstEnd;) {
2082  if (dst0<dstSSEEnd) {
2083  // convert 'rvalues' values at the same time
2084  (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3);
2085 
2086  // increment pointers to the next values
2087  src0 += srcStep;
2088  src1 += srcStep;
2089  dst0 += dstStep;
2090  dst1 += dstStep;
2091  dst2 += dstStep;
2092  dst3 += dstStep;
2093  } else {
2094  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
2095  // convert 1 value
2096  (*subMethod)(src0, src1, dst0, dst1, dst2, dst3);
2097  }
2098 
2099  // move all pointers to the next line
2100  dstLEnd += dstWidth;
2101  dstSSEEnd += dstWidth;
2102  src0 += srcOffset;
2103  src1 += srcOffset;
2104  dst0 += dstOffset;
2105  dst1 += dstOffset;
2106  dst2 += dstOffset;
2107  dst3 += dstOffset;
2108  }
2109  }
2110  }
2111 
2112  template<class S, class D>
2113  inline void sse_for(const S *src0, const S *src1, const S *src2,
2114  D *dst0, D *dstEnd,
2115  long srcWidth, long dstWidth, long lineWidth,
2116  void (*subMethod)(const S*, const S*, const S*, D*),
2117  void (*subSSEMethod)(const S*, const S*, const S*, D*),
2118  long srcStep, long dstStep) {
2119  D *dstLEnd = dst0 + lineWidth;
2120  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2121  long srcOffset = srcWidth - lineWidth;
2122  long dstOffset = dstWidth - lineWidth;
2123  long sStep, dStep;
2124 
2125  if (srcStep < dstStep) {
2126  dStep = dstStep / srcStep;
2127  sStep = 1;
2128  } else {
2129  sStep = srcStep / dstStep;
2130  dStep = 1;
2131  }
2132 
2133  for (; dst0<dstEnd;) {
2134  if (dst0<dstSSEEnd) {
2135  // convert 'rvalues' values at the same time
2136  (*subSSEMethod)(src0, src1, src2, dst0);
2137 
2138  // increment pointers to the next values
2139  src0 += srcStep;
2140  src1 += srcStep;
2141  src2 += srcStep;
2142  dst0 += dstStep;
2143  } else {
2144  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep) {
2145  // convert 1 value
2146  (*subMethod)(src0, src1, src2, dst0);
2147  }
2148 
2149  // move all pointers to the next line
2150  dstLEnd += dstWidth;
2151  dstSSEEnd += dstWidth;
2152  src0 += srcOffset;
2153  src1 += srcOffset;
2154  src2 += srcOffset;
2155  dst0 += dstOffset;
2156  }
2157  }
2158  }
2159 
2160  template<class S, class D>
2161  inline void sse_for(const S *src0, const S *src1, const S *src2,
2162  D *dst0, D *dst1, D *dstEnd,
2163  long srcWidth, long dstWidth, long lineWidth,
2164  void (*subMethod)(const S*, const S*, const S*, D*, D*),
2165  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*),
2166  long srcStep, long dstStep) {
2167  D *dstLEnd = dst0 + lineWidth;
2168  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2169  long srcOffset = srcWidth - lineWidth;
2170  long dstOffset = dstWidth - lineWidth;
2171  long sStep, dStep;
2172 
2173  if (srcStep < dstStep) {
2174  dStep = dstStep / srcStep;
2175  sStep = 1;
2176  } else {
2177  sStep = srcStep / dstStep;
2178  dStep = 1;
2179  }
2180 
2181  for (; dst0<dstEnd;) {
2182  if (dst0<dstSSEEnd) {
2183  // convert 'rvalues' values at the same time
2184  (*subSSEMethod)(src0, src1, src2, dst0, dst1);
2185 
2186  // increment pointers to the next values
2187  src0 += srcStep;
2188  src1 += srcStep;
2189  src2 += srcStep;
2190  dst0 += dstStep;
2191  dst1 += dstStep;
2192  } else {
2193  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep) {
2194  // convert 1 value
2195  (*subMethod)(src0, src1, src2, dst0, dst1);
2196  }
2197 
2198  // move all pointers to the next line
2199  dstLEnd += dstWidth;
2200  dstSSEEnd += dstWidth;
2201  src0 += srcOffset;
2202  src1 += srcOffset;
2203  src2 += srcOffset;
2204  dst0 += dstOffset;
2205  dst1 += dstOffset;
2206  }
2207  }
2208  }
2209 
2210  template<class S, class D>
2211  inline void sse_for(const S *src0, const S *src1, const S *src2,
2212  D *dst0, D *dst1, D *dst2, D *dstEnd,
2213  long srcWidth, long dstWidth, long lineWidth,
2214  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*),
2215  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*),
2216  long srcStep, long dstStep) {
2217  D *dstLEnd = dst0 + lineWidth;
2218  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2219  long srcOffset = srcWidth - lineWidth;
2220  long dstOffset = dstWidth - lineWidth;
2221  long sStep, dStep;
2222 
2223  if (srcStep < dstStep) {
2224  dStep = dstStep / srcStep;
2225  sStep = 1;
2226  } else {
2227  sStep = srcStep / dstStep;
2228  dStep = 1;
2229  }
2230 
2231  for (; dst0<dstEnd;) {
2232  if (dst0<dstSSEEnd) {
2233  // convert 'rvalues' values at the same time
2234  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2);
2235 
2236  // increment pointers to the next values
2237  src0 += srcStep;
2238  src1 += srcStep;
2239  src2 += srcStep;
2240  dst0 += dstStep;
2241  dst1 += dstStep;
2242  dst2 += dstStep;
2243  } else {
2244  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
2245  // convert 1 value
2246  (*subMethod)(src0, src1, src2, dst0, dst1, dst2);
2247  }
2248 
2249  // move all pointers to the next line
2250  dstLEnd += dstWidth;
2251  dstSSEEnd += dstWidth;
2252  src0 += srcOffset;
2253  src1 += srcOffset;
2254  src2 += srcOffset;
2255  dst0 += dstOffset;
2256  dst1 += dstOffset;
2257  dst2 += dstOffset;
2258  }
2259  }
2260  }
2261 
2262  template<class S, class D>
2263  inline void sse_for(const S *src0, const S *src1, const S *src2,
2264  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
2265  long srcWidth, long dstWidth, long lineWidth,
2266  void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
2267  void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*),
2268  long srcStep, long dstStep) {
2269  D *dstLEnd = dst0 + lineWidth;
2270  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2271  long srcOffset = srcWidth - lineWidth;
2272  long dstOffset = dstWidth - lineWidth;
2273  long sStep, dStep;
2274 
2275  if (srcStep < dstStep) {
2276  dStep = dstStep / srcStep;
2277  sStep = 1;
2278  } else {
2279  sStep = srcStep / dstStep;
2280  dStep = 1;
2281  }
2282 
2283  for (; dst0<dstEnd;) {
2284  if (dst0<dstSSEEnd) {
2285  // convert 'rvalues' values at the same time
2286  (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
2287 
2288  // increment pointers to the next values
2289  src0 += srcStep;
2290  src1 += srcStep;
2291  src2 += srcStep;
2292  dst0 += dstStep;
2293  dst1 += dstStep;
2294  dst2 += dstStep;
2295  dst3 += dstStep;
2296  } else {
2297  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
2298  // convert 1 value
2299  (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3);
2300  }
2301 
2302  // move all pointers to the next line
2303  dstLEnd += dstWidth;
2304  dstSSEEnd += dstWidth;
2305  src0 += srcOffset;
2306  src1 += srcOffset;
2307  src2 += srcOffset;
2308  dst0 += dstOffset;
2309  dst1 += dstOffset;
2310  dst2 += dstOffset;
2311  dst3 += dstOffset;
2312  }
2313  }
2314  }
2315 
2316  template<class S, class D>
2317  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
2318  D *dst0, D *dstEnd,
2319  long srcWidth, long dstWidth, long lineWidth,
2320  void (*subMethod)(const S*, const S*, const S*, const S*, D*),
2321  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*),
2322  long srcStep, long dstStep) {
2323  D *dstLEnd = dst0 + lineWidth;
2324  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2325  long srcOffset = srcWidth - lineWidth;
2326  long dstOffset = dstWidth - lineWidth;
2327  long sStep, dStep;
2328 
2329  if (srcStep < dstStep) {
2330  dStep = dstStep / srcStep;
2331  sStep = 1;
2332  } else {
2333  sStep = srcStep / dstStep;
2334  dStep = 1;
2335  }
2336 
2337  for (; dst0<dstEnd;) {
2338  if (dst0<dstSSEEnd) {
2339  // convert 'rvalues' values at the same time
2340  (*subSSEMethod)(src0, src1, src2, src3, dst0);
2341 
2342  // increment pointers to the next values
2343  src0 += srcStep;
2344  src1 += srcStep;
2345  src2 += srcStep;
2346  src3 += srcStep;
2347  dst0 += dstStep;
2348  } else {
2349  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep) {
2350  // convert 1 value
2351  (*subMethod)(src0, src1, src2, src3, dst0);
2352  }
2353 
2354  // move all pointers to the next line
2355  dstLEnd += dstWidth;
2356  dstSSEEnd += dstWidth;
2357  src0 += srcOffset;
2358  src1 += srcOffset;
2359  src2 += srcOffset;
2360  src3 += srcOffset;
2361  dst0 += dstOffset;
2362  }
2363  }
2364  }
2365 
2366  template<class S, class D>
2367  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
2368  D *dst0, D *dst1, D *dstEnd,
2369  long srcWidth, long dstWidth, long lineWidth,
2370  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*),
2371  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*),
2372  long srcStep, long dstStep) {
2373  D *dstLEnd = dst0 + lineWidth;
2374  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2375  long srcOffset = srcWidth - lineWidth;
2376  long dstOffset = dstWidth - lineWidth;
2377  long sStep, dStep;
2378 
2379  if (srcStep < dstStep) {
2380  dStep = dstStep / srcStep;
2381  sStep = 1;
2382  } else {
2383  sStep = srcStep / dstStep;
2384  dStep = 1;
2385  }
2386 
2387  for (; dst0<dstEnd;) {
2388  if (dst0<dstSSEEnd) {
2389  // convert 'rvalues' values at the same time
2390  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1);
2391 
2392  // increment pointers to the next values
2393  src0 += srcStep;
2394  src1 += srcStep;
2395  src2 += srcStep;
2396  src3 += srcStep;
2397  dst0 += dstStep;
2398  dst1 += dstStep;
2399  } else {
2400  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep) {
2401  // convert 1 value
2402  (*subMethod)(src0, src1, src2, src3, dst0, dst1);
2403  }
2404 
2405  // move all pointers to the next line
2406  dstLEnd += dstWidth;
2407  dstSSEEnd += dstWidth;
2408  src0 += srcOffset;
2409  src1 += srcOffset;
2410  src2 += srcOffset;
2411  src3 += srcOffset;
2412  dst0 += dstOffset;
2413  dst1 += dstOffset;
2414  }
2415  }
2416  }
2417 
2418  template<class S, class D>
2419  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
2420  D *dst0, D *dst1, D *dst2, D *dstEnd,
2421  long srcWidth, long dstWidth, long lineWidth,
2422  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
2423  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*),
2424  long srcStep, long dstStep) {
2425  D *dstLEnd = dst0 + lineWidth;
2426  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2427  long srcOffset = srcWidth - lineWidth;
2428  long dstOffset = dstWidth - lineWidth;
2429  long sStep, dStep;
2430 
2431  if (srcStep < dstStep) {
2432  dStep = dstStep / srcStep;
2433  sStep = 1;
2434  } else {
2435  sStep = srcStep / dstStep;
2436  dStep = 1;
2437  }
2438 
2439  for (; dst0<dstEnd;) {
2440  if (dst0<dstSSEEnd) {
2441  // convert 'rvalues' values at the same time
2442  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
2443 
2444  // increment pointers to the next values
2445  src0 += srcStep;
2446  src1 += srcStep;
2447  src2 += srcStep;
2448  src3 += srcStep;
2449  dst0 += dstStep;
2450  dst1 += dstStep;
2451  dst2 += dstStep;
2452  } else {
2453  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) {
2454  // convert 1 value
2455  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2);
2456  }
2457 
2458  // move all pointers to the next line
2459  dstLEnd += dstWidth;
2460  dstSSEEnd += dstWidth;
2461  src0 += srcOffset;
2462  src1 += srcOffset;
2463  src2 += srcOffset;
2464  src3 += srcOffset;
2465  dst0 += dstOffset;
2466  dst1 += dstOffset;
2467  dst2 += dstOffset;
2468  }
2469  }
2470  }
2471 
2472  template<class S, class D>
2473  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3,
2474  D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd,
2475  long srcWidth, long dstWidth, long lineWidth,
2476  void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
2477  void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*),
2478  long srcStep, long dstStep) {
2479  D *dstLEnd = dst0 + lineWidth;
2480  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2481  long srcOffset = srcWidth - lineWidth;
2482  long dstOffset = dstWidth - lineWidth;
2483  long sStep, dStep;
2484 
2485  if (srcStep < dstStep) {
2486  dStep = dstStep / srcStep;
2487  sStep = 1;
2488  } else {
2489  sStep = srcStep / dstStep;
2490  dStep = 1;
2491  }
2492 
2493  for (; dst0<dstEnd;) {
2494  if (dst0<dstSSEEnd) {
2495  // convert 'rvalues' values at the same time
2496  (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
2497 
2498  // increment pointers to the next values
2499  src0 += srcStep;
2500  src1 += srcStep;
2501  src2 += srcStep;
2502  src3 += srcStep;
2503  dst0 += dstStep;
2504  dst1 += dstStep;
2505  dst2 += dstStep;
2506  dst3 += dstStep;
2507  } else {
2508  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) {
2509  // convert 1 value
2510  (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3);
2511  }
2512 
2513  // move all pointers to the next line
2514  dstLEnd += dstWidth;
2515  dstSSEEnd += dstWidth;
2516  src0 += srcOffset;
2517  src1 += srcOffset;
2518  src2 += srcOffset;
2519  src3 += srcOffset;
2520  dst0 += dstOffset;
2521  dst1 += dstOffset;
2522  dst2 += dstOffset;
2523  dst3 += dstOffset;
2524  }
2525  }
2526  }
2527 
2528  template<class S, class D>
2529  inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, const S *src4,
2530  D *dst0, D *dstEnd,
2531  long srcWidth, long dstWidth, long lineWidth,
2532  void (*subMethod)(const S*, const S*, const S*, const S*, const S*, D*),
2533  void (*subSSEMethod)(const S*, const S*, const S*, const S*, const S*, D*),
2534  long srcStep, long dstStep) {
2535  D *dstLEnd = dst0 + lineWidth;
2536  D *dstSSEEnd = dstLEnd - (dstStep - 1);
2537  long srcOffset = srcWidth - lineWidth;
2538  long dstOffset = dstWidth - lineWidth;
2539  long sStep, dStep;
2540 
2541  if (srcStep < dstStep) {
2542  dStep = dstStep / srcStep;
2543  sStep = 1;
2544  } else {
2545  sStep = srcStep / dstStep;
2546  dStep = 1;
2547  }
2548 
2549  for (; dst0<dstEnd;) {
2550  if (dst0<dstSSEEnd) {
2551  // convert 'rvalues' values at the same time
2552  (*subSSEMethod)(src0, src1, src2, src3, src4, dst0);
2553 
2554  // increment pointers to the next values
2555  src0 += srcStep;
2556  src1 += srcStep;
2557  src2 += srcStep;
2558  src3 += srcStep;
2559  src4 += srcStep;
2560  dst0 += dstStep;
2561  } else {
2562  for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, src4 += sStep, dst0 += dStep) {
2563  // convert 1 value
2564  (*subMethod)(src0, src1, src2, src3, src4, dst0);
2565  }
2566 
2567  // move all pointers to the next line
2568  dstLEnd += dstWidth;
2569  dstSSEEnd += dstWidth;
2570  src0 += srcOffset;
2571  src1 += srcOffset;
2572  src2 += srcOffset;
2573  src3 += srcOffset;
2574  src4 += srcOffset;
2575  dst0 += dstOffset;
2576  }
2577  }
2578  }
2579 
2580  // -- for-loops with ROI -- //
2581 
2582  #endif
2583 
2584  } // namespace utils
2585 }
undocument this line if you encounter any issues!
Definition: Any.h:37