Image Component Library (ICL)
|
00001 /******************************************************************** 00002 ** Image Component Library (ICL) ** 00003 ** ** 00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** 00005 ** Neuroinformatics Group ** 00006 ** Website: www.iclcv.org and ** 00007 ** http://opensource.cit-ec.de/projects/icl ** 00008 ** ** 00009 ** File : ICLUtils/src/ICLUtils/SSEUtils.h ** 00010 ** Module : ICLUtils ** 00011 ** Authors: Sergius Gaulik ** 00012 ** ** 00013 ** ** 00014 ** GNU LESSER GENERAL PUBLIC LICENSE ** 00015 ** This file may be used under the terms of the GNU Lesser General ** 00016 ** Public License version 3.0 as published by the ** 00017 ** ** 00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL ** 00019 ** included in the packaging of this file. Please review the ** 00020 ** following information to ensure the license requirements will ** 00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** 00022 ** ** 00023 ** The development of this software was supported by the ** 00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** 00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** 00026 ** Forschungsgemeinschaft (DFG) in the context of the German ** 00027 ** Excellence Initiative. ** 00028 ** ** 00029 ********************************************************************/ 00030 00031 #pragma once 00032 00033 #include <ICLUtils/CompatMacros.h> 00034 #include <ICLUtils/SSETypes.h> 00035 00036 namespace icl{ 00037 namespace utils{ 00038 00039 #ifdef ICL_HAVE_SSE2 00040 00041 // ++ rounding ++ // 00042 00043 // possible modes: 00044 // _MM_ROUND_NEAREST 00045 // _MM_ROUND_DOWN 00046 // _MM_ROUND_UP 00047 // _MM_ROUND_TOWARD_ZERO 00048 00049 static const unsigned int INITIAL_ROUNDING_MODE = _MM_GET_ROUNDING_MODE(); 00050 static unsigned int PREVIOUS_ROUNDING_MODE = INITIAL_ROUNDING_MODE; 00051 00052 inline void sse_restore_initial_rounding_mode() { 00053 _MM_SET_ROUNDING_MODE(INITIAL_ROUNDING_MODE); 00054 } 00055 00056 inline void sse_restore_previous_rounding_mode() { 00057 const unsigned int mode = _MM_GET_ROUNDING_MODE(); 00058 _MM_SET_ROUNDING_MODE(PREVIOUS_ROUNDING_MODE); 00059 PREVIOUS_ROUNDING_MODE = mode; 00060 } 00061 00062 inline void sse_set_rounding_mode(const unsigned int mode) { 00063 PREVIOUS_ROUNDING_MODE = _MM_GET_ROUNDING_MODE(); 00064 _MM_SET_ROUNDING_MODE(mode); 00065 } 00066 00067 // -- rounding -- // 00068 00069 00070 // ++ alignment ++ // 00071 00072 template<class T> 00073 inline int sse_is_16byte_aligned(const T *ptr) { 00074 return !(((uintptr_t)ptr) & 15); 00075 } 00076 00077 template<class T> 00078 inline int sse_is_not_16byte_aligned(const T *ptr) { 00079 return (((uintptr_t)ptr) & 15); 00080 } 00081 00082 template<class T> 00083 inline int sse_is_aligned(const T *ptr, const unsigned int bytes) { 00084 return !(((uintptr_t)ptr) & (bytes-1)); 00085 } 00086 00087 template<class T> 00088 inline int sse_is_not_aligned(const T *ptr, const unsigned int bytes) { 00089 return (((uintptr_t)ptr) & (bytes-1)); 00090 } 00091 00092 // -- alignment -- // 00093 00094 00095 // ++ conditions ++ // 00096 00097 template<class T> 00098 inline T sse_if(const T &vIf, const T &v0) { 00099 T ret = (v0 & vIf); 00100 return ret; 00101 } 00102 00103 template<class T> 00104 inline T sse_ifelse(const T &vIf, const T &v0, const T &v1) { 00105 T ret = (v0 & vIf); 00106 ret += andnot(v1, vIf); 00107 return ret; 00108 } 00109 00110 // -- conditions -- // 00111 00112 00113 // ++ for-loops ++ // 00114 00115 // the sse_for functions can be implemented compact in only one function 00116 // using pointer-to-pointer, but it is slower than the current 00117 // implementation of many versions 00118 00119 template<class S, class D> 00120 inline void sse_for(const S *src0, 00121 D *dst0, D *dstEnd, 00122 void (*subMethod)(const S*, D*), 00123 void (*subSSEMethod)(const S*, D*), 00124 long step) { 00125 D *dstSSEEnd = dstEnd - (step - 1); 00126 00127 for (; dst0<dstSSEEnd;) { 00128 // convert 'rvalues' values at the same time 00129 (*subSSEMethod)(src0, dst0); 00130 00131 // increment pointers to the next values 00132 src0 += step; 00133 dst0 += step; 00134 } 00135 00136 for (; dst0<dstEnd; ++src0, ++dst0) { 00137 // convert 1 value 00138 (*subMethod)(src0, dst0); 00139 } 00140 } 00141 00142 template<class S, class D> 00143 inline void sse_for(const S *src0, 00144 D *dst0, D *dst1, D *dstEnd, 00145 void (*subMethod)(const S*, D*, D*), 00146 void (*subSSEMethod)(const S*, D*, D*), 00147 long step) { 00148 D *dstSSEEnd = dstEnd - (step - 1); 00149 00150 for (; dst0<dstSSEEnd;) { 00151 // convert 'rvalues' values at the same time 00152 (*subSSEMethod)(src0, dst0, dst1); 00153 00154 // increment pointers to the next values 00155 src0 += step; 00156 dst0 += step; 00157 dst1 += step; 00158 } 00159 00160 for (; dst0<dstEnd; ++src0, ++dst0, ++dst1) { 00161 // convert 1 value 00162 (*subMethod)(src0, dst0, dst1); 00163 } 00164 } 00165 00166 template<class S, class D> 00167 inline void sse_for(const S *src0, 00168 D *dst0, D *dst1, D *dst2, D *dstEnd, 00169 void (*subMethod)(const S*, D*, D*, D*), 00170 void (*subSSEMethod)(const S*, D*, D*, D*), 00171 long step) { 00172 D *dstSSEEnd = dstEnd - (step - 1); 00173 00174 for (; dst0<dstSSEEnd;) { 00175 // convert 'rvalues' values at the same time 00176 (*subSSEMethod)(src0, dst0, dst1, dst2); 00177 00178 // increment pointers to the next values 00179 src0 += step; 00180 dst0 += step; 00181 dst1 += step; 00182 dst2 += step; 00183 } 00184 00185 for (; dst0<dstEnd; ++src0, ++dst0, ++dst1, ++dst2) { 00186 // convert 1 value 00187 (*subMethod)(src0, dst0, dst1, dst2); 00188 } 00189 } 00190 00191 template<class S, class D> 00192 inline void sse_for(const S *src0, 00193 D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd, 00194 void (*subMethod)(const S*, D*, D*, D*, D*), 00195 void (*subSSEMethod)(const S*, D*, D*, D*, D*), 00196 long step) { 00197 D *dstSSEEnd = dstEnd - (step - 1); 00198 00199 for (; dst0<dstSSEEnd;) { 00200 // convert 'rvalues' values at the same time 00201 (*subSSEMethod)(src0, dst0, dst1, dst2, dst3); 00202 00203 // increment pointers to the next values 00204 src0 += step; 00205 dst0 += step; 00206 dst1 += step; 00207 dst2 += step; 00208 dst3 += step; 00209 } 00210 00211 for (; dst0<dstEnd; ++src0, ++dst0, ++dst1, ++dst2, ++dst3) { 00212 // convert 1 value 00213 (*subMethod)(src0, dst0, dst1, dst2, dst3); 00214 } 00215 } 00216 00217 template<class S, class D> 00218 inline void sse_for(const S *src0, const S *src1, 00219 D *dst0, D *dstEnd, 00220 void (*subMethod)(const S*, const S*, D*), 00221 void (*subSSEMethod)(const S*, const S*, D*), 00222 long step) { 00223 D *dstSSEEnd = dstEnd - (step - 1); 00224 00225 for (; dst0<dstSSEEnd;) { 00226 // convert 'rvalues' values at the same time 00227 (*subSSEMethod)(src0, src1, dst0); 00228 00229 // increment pointers to the next values 00230 src0 += step; 00231 src1 += step; 00232 dst0 += step; 00233 } 00234 00235 for (; dst0<dstEnd; ++src0, ++src1, ++dst0) { 00236 // convert 1 value 00237 (*subMethod)(src0, src1, dst0); 00238 } 00239 } 00240 00241 template<class S, class D> 00242 inline void sse_for(const S *src0, const S *src1, 00243 D *dst0, D *dst1, D *dstEnd, 00244 void (*subMethod)(const S*, const S*, D*, D*), 00245 void (*subSSEMethod)(const S*, const S*, D*, D*), 00246 long step) { 00247 D *dstSSEEnd = dstEnd - (step - 1); 00248 00249 for (; dst0<dstSSEEnd;) { 00250 // convert 'rvalues' values at the same time 00251 (*subSSEMethod)(src0, src1, dst0, dst1); 00252 00253 // increment pointers to the next values 00254 src0 += step; 00255 src1 += step; 00256 dst0 += step; 00257 dst1 += step; 00258 } 00259 00260 for (; dst0<dstEnd; ++src0, ++src1, ++dst0, ++dst1) { 00261 // convert 1 value 00262 (*subMethod)(src0, src1, dst0, dst1); 00263 } 00264 } 00265 00266 template<class S, class D> 00267 inline void sse_for(const S *src0, const S *src1, 00268 D *dst0, D *dst1, D *dst2, D *dstEnd, 00269 void (*subMethod)(const S*, const S*, D*, D*, D*), 00270 void (*subSSEMethod)(const S*, const S*, D*, D*, D*), 00271 long step) { 00272 D *dstSSEEnd = dstEnd - (step - 1); 00273 00274 for (; dst0<dstSSEEnd;) { 00275 // convert 'rvalues' values at the same time 00276 (*subSSEMethod)(src0, src1, dst0, dst1, dst2); 00277 00278 // increment pointers to the next values 00279 src0 += step; 00280 src1 += step; 00281 dst0 += step; 00282 dst1 += step; 00283 dst2 += step; 00284 } 00285 00286 for (; dst0<dstEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2) { 00287 // convert 1 value 00288 (*subMethod)(src0, src1, dst0, dst1, dst2); 00289 } 00290 } 00291 00292 template<class S, class D> 00293 inline void sse_for(const S *src0, const S *src1, 00294 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 00295 void (*subMethod)(const S*, const S*, D*, D*, D*, D*), 00296 void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*), 00297 long step) { 00298 D *dstSSEEnd = dstEnd - (step - 1); 00299 00300 for (; dst0<dstSSEEnd;) { 00301 // convert 'rvalues' values at the same time 00302 (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3); 00303 00304 // increment pointers to the next values 00305 src0 += step; 00306 src1 += step; 00307 dst0 += step; 00308 dst1 += step; 00309 dst2 += step; 00310 dst3 += step; 00311 } 00312 00313 for (; dst0<dstEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2, ++dst3) { 00314 // convert 1 value 00315 (*subMethod)(src0, src1, dst0, dst1, dst2, dst3); 00316 } 00317 } 00318 00319 template<class S, class D> 00320 inline void sse_for(const S *src0, const S *src1, const S *src2, 00321 D *dst0, D *dstEnd, 00322 void (*subMethod)(const S*, const S*, const S*, D*), 00323 void (*subSSEMethod)(const S*, const S*, const S*, D*), 00324 long step) { 00325 D *dstSSEEnd = dstEnd - (step - 1); 00326 00327 for (; dst0<dstSSEEnd;) { 00328 // convert 'rvalues' values at the same time 00329 (*subSSEMethod)(src0, src1, src2, dst0); 00330 00331 // increment pointers to the next values 00332 src0 += step; 00333 src1 += step; 00334 src2 += step; 00335 dst0 += step; 00336 } 00337 00338 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0) { 00339 // convert 1 value 00340 (*subMethod)(src0, src1, src2, dst0); 00341 } 00342 } 00343 00344 template<class S, class D> 00345 inline void sse_for(const S *src0, const S *src1, const S *src2, 00346 D *dst0, D *dst1, D *dstEnd, 00347 void (*subMethod)(const S*, const S*, const S*, D*, D*), 00348 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*), 00349 long step) { 00350 D *dstSSEEnd = dstEnd - (step - 1); 00351 00352 for (; dst0<dstSSEEnd;) { 00353 // convert 'rvalues' values at the same time 00354 (*subSSEMethod)(src0, src1, src2, dst0, dst1); 00355 00356 // increment pointers to the next values 00357 src0 += step; 00358 src1 += step; 00359 src2 += step; 00360 dst0 += step; 00361 dst1 += step; 00362 } 00363 00364 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1) { 00365 // convert 1 value 00366 (*subMethod)(src0, src1, src2, dst0, dst1); 00367 } 00368 } 00369 00370 template<class S, class D> 00371 inline void sse_for(const S *src0, const S *src1, const S *src2, 00372 D *dst0, D *dst1, D *dst2, D *dstEnd, 00373 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*), 00374 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*), 00375 long step) { 00376 D *dstSSEEnd = dstEnd - (step - 1); 00377 00378 for (; dst0<dstSSEEnd;) { 00379 // convert 'rvalues' values at the same time 00380 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2); 00381 00382 // increment pointers to the next values 00383 src0 += step; 00384 src1 += step; 00385 src2 += step; 00386 dst0 += step; 00387 dst1 += step; 00388 dst2 += step; 00389 } 00390 00391 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2) { 00392 // convert 1 value 00393 (*subMethod)(src0, src1, src2, dst0, dst1, dst2); 00394 } 00395 } 00396 00397 template<class S, class D> 00398 inline void sse_for(const S *src0, const S *src1, const S *src2, 00399 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 00400 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 00401 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 00402 long step) { 00403 D *dstSSEEnd = dstEnd - (step - 1); 00404 00405 for (; dst0<dstSSEEnd;) { 00406 // convert 'rvalues' values at the same time 00407 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 00408 00409 // increment pointers to the next values 00410 src0 += step; 00411 src1 += step; 00412 src2 += step; 00413 dst0 += step; 00414 dst1 += step; 00415 dst2 += step; 00416 dst3 += step; 00417 } 00418 00419 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2, ++dst3) { 00420 // convert 1 value 00421 (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 00422 } 00423 } 00424 00425 template<class S, class D> 00426 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 00427 D *dst0, D *dstEnd, 00428 void (*subMethod)(const S*, const S*, const S*, const S*, D*), 00429 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*), 00430 long step) { 00431 D *dstSSEEnd = dstEnd - (step - 1); 00432 00433 for (; dst0<dstSSEEnd;) { 00434 // convert 'rvalues' values at the same time 00435 (*subSSEMethod)(src0, src1, src2, src3, dst0); 00436 00437 // increment pointers to the next values 00438 src0 += step; 00439 src1 += step; 00440 src2 += step; 00441 src3 += step; 00442 dst0 += step; 00443 } 00444 00445 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0) { 00446 // convert 1 value 00447 (*subMethod)(src0, src1, src2, src3, dst0); 00448 } 00449 } 00450 00451 template<class S, class D> 00452 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 00453 D *dst0, D *dst1, D *dstEnd, 00454 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*), 00455 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*), 00456 long step) { 00457 D *dstSSEEnd = dstEnd - (step - 1); 00458 00459 for (; dst0<dstSSEEnd;) { 00460 // convert 'rvalues' values at the same time 00461 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1); 00462 00463 // increment pointers to the next values 00464 src0 += step; 00465 src1 += step; 00466 src2 += step; 00467 src3 += step; 00468 dst0 += step; 00469 dst1 += step; 00470 } 00471 00472 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1) { 00473 // convert 1 value 00474 (*subMethod)(src0, src1, src2, src3, dst0, dst1); 00475 } 00476 } 00477 00478 template<class S, class D> 00479 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 00480 D *dst0, D *dst1, D *dst2, D *dstEnd, 00481 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 00482 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 00483 long step) { 00484 D *dstSSEEnd = dstEnd - (step - 1); 00485 00486 for (; dst0<dstSSEEnd;) { 00487 // convert 'rvalues' values at the same time 00488 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 00489 00490 // increment pointers to the next values 00491 src0 += step; 00492 src1 += step; 00493 src2 += step; 00494 src3 += step; 00495 dst0 += step; 00496 dst1 += step; 00497 dst2 += step; 00498 } 00499 00500 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2) { 00501 // convert 1 value 00502 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 00503 } 00504 } 00505 00506 template<class S, class D> 00507 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 00508 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 00509 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 00510 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 00511 long step) { 00512 D *dstSSEEnd = dstEnd - (step - 1); 00513 00514 for (; dst0<dstSSEEnd;) { 00515 // convert 'rvalues' values at the same time 00516 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 00517 00518 // increment pointers to the next values 00519 src0 += step; 00520 src1 += step; 00521 src2 += step; 00522 src3 += step; 00523 dst0 += step; 00524 dst1 += step; 00525 dst2 += step; 00526 dst3 += step; 00527 } 00528 00529 for (; dst0<dstEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2, ++dst3) { 00530 // convert 1 value 00531 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 00532 } 00533 } 00534 00535 // the sse_for functions can be implemented compact in only one function 00536 // using pointer-to-pointer, but it is slower than the current 00537 // implementation of many versions 00538 00539 template<class S, class D> 00540 inline void sse_for(const S *src0, 00541 D *dst0, D *dstEnd, 00542 void (*subMethod)(const S*, D*), 00543 void (*subSSEMethod)(const S*, D*), 00544 long srcStep, long dstStep) { 00545 D *dstSSEEnd = dstEnd - (dstStep - 1); 00546 long sStep, dStep; 00547 00548 if (srcStep < dstStep) { 00549 dStep = dstStep / srcStep; 00550 sStep = 1; 00551 } else { 00552 sStep = srcStep / dstStep; 00553 dStep = 1; 00554 } 00555 00556 for (; dst0<dstSSEEnd;) { 00557 // convert 'rvalues' values at the same time 00558 (*subSSEMethod)(src0, dst0); 00559 00560 // increment pointers to the next values 00561 src0 += srcStep; 00562 dst0 += dstStep; 00563 } 00564 00565 for (; dst0<dstEnd; src0 += sStep, dst0 += dStep) { 00566 // convert 1 value 00567 (*subMethod)(src0, dst0); 00568 } 00569 } 00570 00571 template<class S, class D> 00572 inline void sse_for(const S *src0, 00573 D *dst0, D *dst1, D *dstEnd, 00574 void (*subMethod)(const S*, D*, D*), 00575 void (*subSSEMethod)(const S*, D*, D*), 00576 long srcStep, long dstStep) { 00577 D *dstSSEEnd = dstEnd - (dstStep - 1); 00578 long sStep, dStep; 00579 00580 if (srcStep < dstStep) { 00581 dStep = dstStep / srcStep; 00582 sStep = 1; 00583 } else { 00584 sStep = srcStep / dstStep; 00585 dStep = 1; 00586 } 00587 00588 for (; dst0<dstSSEEnd;) { 00589 // convert 'rvalues' values at the same time 00590 (*subSSEMethod)(src0, dst0, dst1); 00591 00592 // increment pointers to the next values 00593 src0 += srcStep; 00594 dst0 += dstStep; 00595 dst1 += dstStep; 00596 } 00597 00598 for (; dst0<dstEnd; src0 += sStep, dst0 += dStep, dst1 += dStep) { 00599 // convert 1 value 00600 (*subMethod)(src0, dst0, dst1); 00601 } 00602 } 00603 00604 template<class S, class D> 00605 inline void sse_for(const S *src0, 00606 D *dst0, D *dst1, D *dst2, D *dstEnd, 00607 void (*subMethod)(const S*, D*, D*, D*), 00608 void (*subSSEMethod)(const S*, D*, D*, D*), 00609 long srcStep, long dstStep) { 00610 D *dstSSEEnd = dstEnd - (dstStep - 1); 00611 long sStep, dStep; 00612 00613 if (srcStep < dstStep) { 00614 dStep = dstStep / srcStep; 00615 sStep = 1; 00616 } else { 00617 sStep = srcStep / dstStep; 00618 dStep = 1; 00619 } 00620 00621 for (; dst0<dstSSEEnd;) { 00622 // convert 'rvalues' values at the same time 00623 (*subSSEMethod)(src0, dst0, dst1, dst2); 00624 00625 // increment pointers to the next values 00626 src0 += srcStep; 00627 dst0 += dstStep; 00628 dst1 += dstStep; 00629 dst2 += dstStep; 00630 } 00631 00632 for (; dst0<dstEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 00633 // convert 1 value 00634 (*subMethod)(src0, dst0, dst1, dst2); 00635 } 00636 } 00637 00638 template<class S, class D> 00639 inline void sse_for(const S *src0, 00640 D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd, 00641 void (*subMethod)(const S*, D*, D*, D*, D*), 00642 void (*subSSEMethod)(const S*, D*, D*, D*, D*), 00643 long srcStep, long dstStep) { 00644 D *dstSSEEnd = dstEnd - (dstStep - 1); 00645 long sStep, dStep; 00646 00647 if (srcStep < dstStep) { 00648 dStep = dstStep / srcStep; 00649 sStep = 1; 00650 } else { 00651 sStep = srcStep / dstStep; 00652 dStep = 1; 00653 } 00654 00655 for (; dst0<dstSSEEnd;) { 00656 // convert 'rvalues' values at the same time 00657 (*subSSEMethod)(src0, dst0, dst1, dst2, dst3); 00658 00659 // increment pointers to the next values 00660 src0 += srcStep; 00661 dst0 += dstStep; 00662 dst1 += dstStep; 00663 dst2 += dstStep; 00664 dst3 += dstStep; 00665 } 00666 00667 for (; dst0<dstEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 00668 // convert 1 value 00669 (*subMethod)(src0, dst0, dst1, dst2, dst3); 00670 } 00671 } 00672 00673 template<class S, class D> 00674 inline void sse_for(const S *src0, const S *src1, 00675 D *dst0, D *dstEnd, 00676 void (*subMethod)(const S*, const S*, D*), 00677 void (*subSSEMethod)(const S*, const S*, D*), 00678 long srcStep, long dstStep) { 00679 D *dstSSEEnd = dstEnd - (dstStep - 1); 00680 long sStep, dStep; 00681 00682 if (srcStep < dstStep) { 00683 dStep = dstStep / srcStep; 00684 sStep = 1; 00685 } else { 00686 sStep = srcStep / dstStep; 00687 dStep = 1; 00688 } 00689 00690 for (; dst0<dstSSEEnd;) { 00691 // convert 'rvalues' values at the same time 00692 (*subSSEMethod)(src0, src1, dst0); 00693 00694 // increment pointers to the next values 00695 src0 += srcStep; 00696 src1 += srcStep; 00697 dst0 += dstStep; 00698 } 00699 00700 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep) { 00701 // convert 1 value 00702 (*subMethod)(src0, src1, dst0); 00703 } 00704 } 00705 00706 template<class S, class D> 00707 inline void sse_for(const S *src0, const S *src1, 00708 D *dst0, D *dst1, D *dstEnd, 00709 void (*subMethod)(const S*, const S*, D*, D*), 00710 void (*subSSEMethod)(const S*, const S*, D*, D*), 00711 long srcStep, long dstStep) { 00712 D *dstSSEEnd = dstEnd - (dstStep - 1); 00713 long sStep, dStep; 00714 00715 if (srcStep < dstStep) { 00716 dStep = dstStep / srcStep; 00717 sStep = 1; 00718 } else { 00719 sStep = srcStep / dstStep; 00720 dStep = 1; 00721 } 00722 00723 for (; dst0<dstSSEEnd;) { 00724 // convert 'rvalues' values at the same time 00725 (*subSSEMethod)(src0, src1, dst0, dst1); 00726 00727 // increment pointers to the next values 00728 src0 += srcStep; 00729 src1 += srcStep; 00730 dst0 += dstStep; 00731 dst1 += dstStep; 00732 } 00733 00734 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep) { 00735 // convert 1 value 00736 (*subMethod)(src0, src1, dst0, dst1); 00737 } 00738 } 00739 00740 template<class S, class D> 00741 inline void sse_for(const S *src0, const S *src1, 00742 D *dst0, D *dst1, D *dst2, D *dstEnd, 00743 void (*subMethod)(const S*, const S*, D*, D*, D*), 00744 void (*subSSEMethod)(const S*, const S*, D*, D*, D*), 00745 long srcStep, long dstStep) { 00746 D *dstSSEEnd = dstEnd - (dstStep - 1); 00747 long sStep, dStep; 00748 00749 if (srcStep < dstStep) { 00750 dStep = dstStep / srcStep; 00751 sStep = 1; 00752 } else { 00753 sStep = srcStep / dstStep; 00754 dStep = 1; 00755 } 00756 00757 for (; dst0<dstSSEEnd;) { 00758 // convert 'rvalues' values at the same time 00759 (*subSSEMethod)(src0, src1, dst0, dst1, dst2); 00760 00761 // increment pointers to the next values 00762 src0 += srcStep; 00763 src1 += srcStep; 00764 dst0 += dstStep; 00765 dst1 += dstStep; 00766 dst2 += dstStep; 00767 } 00768 00769 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 00770 // convert 1 value 00771 (*subMethod)(src0, src1, dst0, dst1, dst2); 00772 } 00773 } 00774 00775 template<class S, class D> 00776 inline void sse_for(const S *src0, const S *src1, 00777 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 00778 void (*subMethod)(const S*, const S*, D*, D*, D*, D*), 00779 void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*), 00780 long srcStep, long dstStep) { 00781 D *dstSSEEnd = dstEnd - (dstStep - 1); 00782 long sStep, dStep; 00783 00784 if (srcStep < dstStep) { 00785 dStep = dstStep / srcStep; 00786 sStep = 1; 00787 } else { 00788 sStep = srcStep / dstStep; 00789 dStep = 1; 00790 } 00791 00792 for (; dst0<dstSSEEnd;) { 00793 // convert 'rvalues' values at the same time 00794 (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3); 00795 00796 // increment pointers to the next values 00797 src0 += srcStep; 00798 src1 += srcStep; 00799 dst0 += dstStep; 00800 dst1 += dstStep; 00801 dst2 += dstStep; 00802 dst3 += dstStep; 00803 } 00804 00805 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 00806 // convert 1 value 00807 (*subMethod)(src0, src1, dst0, dst1, dst2, dst3); 00808 } 00809 } 00810 00811 template<class S, class D> 00812 inline void sse_for(const S *src0, const S *src1, const S *src2, 00813 D *dst0, D *dstEnd, 00814 void (*subMethod)(const S*, const S*, const S*, D*), 00815 void (*subSSEMethod)(const S*, const S*, const S*, D*), 00816 long srcStep, long dstStep) { 00817 D *dstSSEEnd = dstEnd - (dstStep - 1); 00818 long sStep, dStep; 00819 00820 if (srcStep < dstStep) { 00821 dStep = dstStep / srcStep; 00822 sStep = 1; 00823 } else { 00824 sStep = srcStep / dstStep; 00825 dStep = 1; 00826 } 00827 00828 for (; dst0<dstSSEEnd;) { 00829 // convert 'rvalues' values at the same time 00830 (*subSSEMethod)(src0, src1, src2, dst0); 00831 00832 // increment pointers to the next values 00833 src0 += srcStep; 00834 src1 += srcStep; 00835 src2 += srcStep; 00836 dst0 += dstStep; 00837 } 00838 00839 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep) { 00840 // convert 1 value 00841 (*subMethod)(src0, src1, src2, dst0); 00842 } 00843 } 00844 00845 template<class S, class D> 00846 inline void sse_for(const S *src0, const S *src1, const S *src2, 00847 D *dst0, D *dst1, D *dstEnd, 00848 void (*subMethod)(const S*, const S*, const S*, D*, D*), 00849 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*), 00850 long srcStep, long dstStep) { 00851 D *dstSSEEnd = dstEnd - (dstStep - 1); 00852 long sStep, dStep; 00853 00854 if (srcStep < dstStep) { 00855 dStep = dstStep / srcStep; 00856 sStep = 1; 00857 } else { 00858 sStep = srcStep / dstStep; 00859 dStep = 1; 00860 } 00861 00862 for (; dst0<dstSSEEnd;) { 00863 // convert 'rvalues' values at the same time 00864 (*subSSEMethod)(src0, src1, src2, dst0, dst1); 00865 00866 // increment pointers to the next values 00867 src0 += srcStep; 00868 src1 += srcStep; 00869 src2 += srcStep; 00870 dst0 += dstStep; 00871 dst1 += dstStep; 00872 } 00873 00874 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep) { 00875 // convert 1 value 00876 (*subMethod)(src0, src1, src2, dst0, dst1); 00877 } 00878 } 00879 00880 template<class S, class D> 00881 inline void sse_for(const S *src0, const S *src1, const S *src2, 00882 D *dst0, D *dst1, D *dst2, D *dstEnd, 00883 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*), 00884 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*), 00885 long srcStep, long dstStep) { 00886 D *dstSSEEnd = dstEnd - (dstStep - 1); 00887 long sStep, dStep; 00888 00889 if (srcStep < dstStep) { 00890 dStep = dstStep / srcStep; 00891 sStep = 1; 00892 } else { 00893 sStep = srcStep / dstStep; 00894 dStep = 1; 00895 } 00896 00897 for (; dst0<dstSSEEnd;) { 00898 // convert 'rvalues' values at the same time 00899 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2); 00900 00901 // increment pointers to the next values 00902 src0 += srcStep; 00903 src1 += srcStep; 00904 src2 += srcStep; 00905 dst0 += dstStep; 00906 dst1 += dstStep; 00907 dst2 += dstStep; 00908 } 00909 00910 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 00911 // convert 1 value 00912 (*subMethod)(src0, src1, src2, dst0, dst1, dst2); 00913 } 00914 } 00915 00916 template<class S, class D> 00917 inline void sse_for(const S *src0, const S *src1, const S *src2, 00918 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 00919 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 00920 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 00921 long srcStep, long dstStep) { 00922 D *dstSSEEnd = dstEnd - (dstStep - 1); 00923 long sStep, dStep; 00924 00925 if (srcStep < dstStep) { 00926 dStep = dstStep / srcStep; 00927 sStep = 1; 00928 } else { 00929 sStep = srcStep / dstStep; 00930 dStep = 1; 00931 } 00932 00933 for (; dst0<dstSSEEnd;) { 00934 // convert 'rvalues' values at the same time 00935 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 00936 00937 // increment pointers to the next values 00938 src0 += srcStep; 00939 src1 += srcStep; 00940 src2 += srcStep; 00941 dst0 += dstStep; 00942 dst1 += dstStep; 00943 dst2 += dstStep; 00944 dst3 += dstStep; 00945 } 00946 00947 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 00948 // convert 1 value 00949 (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 00950 } 00951 } 00952 00953 template<class S, class D> 00954 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 00955 D *dst0, D *dstEnd, 00956 void (*subMethod)(const S*, const S*, const S*, const S*, D*), 00957 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*), 00958 long srcStep, long dstStep) { 00959 D *dstSSEEnd = dstEnd - (dstStep - 1); 00960 long sStep, dStep; 00961 00962 if (srcStep < dstStep) { 00963 dStep = dstStep / srcStep; 00964 sStep = 1; 00965 } else { 00966 sStep = srcStep / dstStep; 00967 dStep = 1; 00968 } 00969 00970 for (; dst0<dstSSEEnd;) { 00971 // convert 'rvalues' values at the same time 00972 (*subSSEMethod)(src0, src1, src2, src3, dst0); 00973 00974 // increment pointers to the next values 00975 src0 += srcStep; 00976 src1 += srcStep; 00977 src2 += srcStep; 00978 src3 += srcStep; 00979 dst0 += dstStep; 00980 } 00981 00982 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep) { 00983 // convert 1 value 00984 (*subMethod)(src0, src1, src2, src3, dst0); 00985 } 00986 } 00987 00988 template<class S, class D> 00989 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 00990 D *dst0, D *dst1, D *dstEnd, 00991 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*), 00992 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*), 00993 long srcStep, long dstStep) { 00994 D *dstSSEEnd = dstEnd - (dstStep - 1); 00995 long sStep, dStep; 00996 00997 if (srcStep < dstStep) { 00998 dStep = dstStep / srcStep; 00999 sStep = 1; 01000 } else { 01001 sStep = srcStep / dstStep; 01002 dStep = 1; 01003 } 01004 01005 for (; dst0<dstSSEEnd;) { 01006 // convert 'rvalues' values at the same time 01007 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1); 01008 01009 // increment pointers to the next values 01010 src0 += srcStep; 01011 src1 += srcStep; 01012 src2 += srcStep; 01013 src3 += srcStep; 01014 dst0 += dstStep; 01015 dst1 += dstStep; 01016 } 01017 01018 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep) { 01019 // convert 1 value 01020 (*subMethod)(src0, src1, src2, src3, dst0, dst1); 01021 } 01022 } 01023 01024 template<class S, class D> 01025 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 01026 D *dst0, D *dst1, D *dst2, D *dstEnd, 01027 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 01028 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 01029 long srcStep, long dstStep) { 01030 D *dstSSEEnd = dstEnd - (dstStep - 1); 01031 long sStep, dStep; 01032 01033 if (srcStep < dstStep) { 01034 dStep = dstStep / srcStep; 01035 sStep = 1; 01036 } else { 01037 sStep = srcStep / dstStep; 01038 dStep = 1; 01039 } 01040 01041 for (; dst0<dstSSEEnd;) { 01042 // convert 'rvalues' values at the same time 01043 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 01044 01045 // increment pointers to the next values 01046 src0 += srcStep; 01047 src1 += srcStep; 01048 src2 += srcStep; 01049 src3 += srcStep; 01050 dst0 += dstStep; 01051 dst1 += dstStep; 01052 dst2 += dstStep; 01053 } 01054 01055 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 01056 // convert 1 value 01057 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 01058 } 01059 } 01060 01061 template<class S, class D> 01062 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 01063 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 01064 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 01065 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 01066 long srcStep, long dstStep) { 01067 D *dstSSEEnd = dstEnd - (dstStep - 1); 01068 long sStep, dStep; 01069 01070 if (srcStep < dstStep) { 01071 dStep = dstStep / srcStep; 01072 sStep = 1; 01073 } else { 01074 sStep = srcStep / dstStep; 01075 dStep = 1; 01076 } 01077 01078 for (; dst0<dstSSEEnd;) { 01079 // convert 'rvalues' values at the same time 01080 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 01081 01082 // increment pointers to the next values 01083 src0 += srcStep; 01084 src1 += srcStep; 01085 src2 += srcStep; 01086 src3 += srcStep; 01087 dst0 += dstStep; 01088 dst1 += dstStep; 01089 dst2 += dstStep; 01090 dst3 += dstStep; 01091 } 01092 01093 for (; dst0<dstEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 01094 // convert 1 value 01095 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 01096 } 01097 } 01098 01099 // -- for-loops -- // 01100 01101 01102 // ++ for-loops with ROI ++ // 01103 01104 // the sse_for functions can be implemented compact in only one function 01105 // using pointer-to-pointer, but it is slower than the current 01106 // implementation of many versions 01107 01108 template<class S, class D> 01109 inline void sse_for(const S *src0, 01110 D *dst0, D *dstEnd, 01111 long srcWidth, long dstWidth, long lineWidth, 01112 void (*subMethod)(const S*, D*), 01113 void (*subSSEMethod)(const S*, D*), 01114 long step) { 01115 D *dstLEnd = dst0 + lineWidth; 01116 D *dstSSEEnd = dstLEnd - (step - 1); 01117 long srcOffset = srcWidth - lineWidth; 01118 long dstOffset = dstWidth - lineWidth; 01119 01120 for (; dst0<dstEnd;) { 01121 if (dst0<dstSSEEnd) { 01122 // convert 'rvalues' values at the same time 01123 (*subSSEMethod)(src0, dst0); 01124 01125 // increment pointers to the next values 01126 src0 += step; 01127 dst0 += step; 01128 } else { 01129 for (; dst0<dstLEnd; ++src0, ++dst0) { 01130 // convert 1 value 01131 (*subMethod)(src0, dst0); 01132 } 01133 01134 // move all pointers to the next line 01135 dstLEnd += dstWidth; 01136 dstSSEEnd += dstWidth; 01137 src0 += srcOffset; 01138 dst0 += dstOffset; 01139 } 01140 } 01141 } 01142 01143 template<class S, class D> 01144 inline void sse_for(const S *src0, 01145 D *dst0, D *dst1, D *dstEnd, 01146 long srcWidth, long dstWidth, long lineWidth, 01147 void (*subMethod)(const S*, D*, D*), 01148 void (*subSSEMethod)(const S*, D*, D*), 01149 long step) { 01150 D *dstLEnd = dst0 + lineWidth; 01151 D *dstSSEEnd = dstLEnd - (step - 1); 01152 long srcOffset = srcWidth - lineWidth; 01153 long dstOffset = dstWidth - lineWidth; 01154 01155 for (; dst0<dstEnd;) { 01156 if (dst0<dstSSEEnd) { 01157 // convert 'rvalues' values at the same time 01158 (*subSSEMethod)(src0, dst0, dst1); 01159 01160 // increment pointers to the next values 01161 src0 += step; 01162 dst0 += step; 01163 dst1 += step; 01164 } else { 01165 for (; dst0<dstLEnd; ++src0, ++dst0, ++dst1) { 01166 // convert 1 value 01167 (*subMethod)(src0, dst0, dst1); 01168 } 01169 01170 // move all pointers to the next line 01171 dstLEnd += dstWidth; 01172 dstSSEEnd += dstWidth; 01173 src0 += srcOffset; 01174 dst0 += dstOffset; 01175 dst1 += dstOffset; 01176 } 01177 } 01178 } 01179 01180 template<class S, class D> 01181 inline void sse_for(const S *src0, 01182 D *dst0, D *dst1, D *dst2, D *dstEnd, 01183 long srcWidth, long dstWidth, long lineWidth, 01184 void (*subMethod)(const S*, D*, D*, D*), 01185 void (*subSSEMethod)(const S*, D*, D*, D*), 01186 long step) { 01187 D *dstLEnd = dst0 + lineWidth; 01188 D *dstSSEEnd = dstLEnd - (step - 1); 01189 long srcOffset = srcWidth - lineWidth; 01190 long dstOffset = dstWidth - lineWidth; 01191 01192 for (; dst0<dstEnd;) { 01193 if (dst0<dstSSEEnd) { 01194 // convert 'rvalues' values at the same time 01195 (*subSSEMethod)(src0, dst0, dst1, dst2); 01196 01197 // increment pointers to the next values 01198 src0 += step; 01199 dst0 += step; 01200 dst1 += step; 01201 dst2 += step; 01202 } else { 01203 for (; dst0<dstLEnd; ++src0, ++dst0, ++dst1, ++dst2) { 01204 // convert 1 value 01205 (*subMethod)(src0, dst0, dst1, dst2); 01206 } 01207 01208 // move all pointers to the next line 01209 dstLEnd += dstWidth; 01210 dstSSEEnd += dstWidth; 01211 src0 += srcOffset; 01212 dst0 += dstOffset; 01213 dst1 += dstOffset; 01214 dst2 += dstOffset; 01215 } 01216 } 01217 } 01218 01219 template<class S, class D> 01220 inline void sse_for(const S *src0, 01221 D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd, 01222 long srcWidth, long dstWidth, long lineWidth, 01223 void (*subMethod)(const S*, D*, D*, D*, D*), 01224 void (*subSSEMethod)(const S*, D*, D*, D*, D*), 01225 long step) { 01226 D *dstLEnd = dst0 + lineWidth; 01227 D *dstSSEEnd = dstLEnd - (step - 1); 01228 long srcOffset = srcWidth - lineWidth; 01229 long dstOffset = dstWidth - lineWidth; 01230 01231 for (; dst0<dstEnd;) { 01232 if (dst0<dstSSEEnd) { 01233 // convert 'rvalues' values at the same time 01234 (*subSSEMethod)(src0, dst0, dst1, dst2, dst3); 01235 01236 // increment pointers to the next values 01237 src0 += step; 01238 dst0 += step; 01239 dst1 += step; 01240 dst2 += step; 01241 dst3 += step; 01242 } else { 01243 for (; dst0<dstLEnd; ++src0, ++dst0, ++dst1, ++dst2, ++dst3) { 01244 // convert 1 value 01245 (*subMethod)(src0, dst0, dst1, dst2, dst3); 01246 } 01247 01248 // move all pointers to the next line 01249 dstLEnd += dstWidth; 01250 dstSSEEnd += dstWidth; 01251 src0 += srcOffset; 01252 dst0 += dstOffset; 01253 dst1 += dstOffset; 01254 dst2 += dstOffset; 01255 dst3 += dstOffset; 01256 } 01257 } 01258 } 01259 01260 template<class S, class D> 01261 inline void sse_for(const S *src0, const S *src1, 01262 D *dst0, D *dst1, D *dstEnd, 01263 long srcWidth, long dstWidth, long lineWidth, 01264 void (*subMethod)(const S*, const S*, D*, D*), 01265 void (*subSSEMethod)(const S*, const S*, D*, D*), 01266 long step) { 01267 D *dstLEnd = dst0 + lineWidth; 01268 D *dstSSEEnd = dstLEnd - (step - 1); 01269 long srcOffset = srcWidth - lineWidth; 01270 long dstOffset = dstWidth - lineWidth; 01271 01272 for (; dst0<dstEnd;) { 01273 if (dst0<dstSSEEnd) { 01274 // convert 'rvalues' values at the same time 01275 (*subSSEMethod)(src0, src1, dst0, dst1); 01276 01277 // increment pointers to the next values 01278 src0 += step; 01279 src1 += step; 01280 dst0 += step; 01281 dst1 += step; 01282 } else { 01283 for (; dst0<dstLEnd; ++src0, ++src1, ++dst0, ++dst1) { 01284 // convert 1 value 01285 (*subMethod)(src0, src1, dst0, dst1); 01286 } 01287 01288 // move all pointers to the next line 01289 dstLEnd += dstWidth; 01290 dstSSEEnd += dstWidth; 01291 src0 += srcOffset; 01292 src1 += srcOffset; 01293 dst0 += dstOffset; 01294 dst1 += dstOffset; 01295 } 01296 } 01297 } 01298 01299 template<class S, class D> 01300 inline void sse_for(const S *src0, const S *src1, 01301 D *dst0, D *dst1, D *dst2, D *dstEnd, 01302 long srcWidth, long dstWidth, long lineWidth, 01303 void (*subMethod)(const S*, const S*, D*, D*, D*), 01304 void (*subSSEMethod)(const S*, const S*, D*, D*, D*), 01305 long step) { 01306 D *dstLEnd = dst0 + lineWidth; 01307 D *dstSSEEnd = dstLEnd - (step - 1); 01308 long srcOffset = srcWidth - lineWidth; 01309 long dstOffset = dstWidth - lineWidth; 01310 01311 for (; dst0<dstEnd;) { 01312 if (dst0<dstSSEEnd) { 01313 // convert 'rvalues' values at the same time 01314 (*subSSEMethod)(src0, src1, dst0, dst1, dst2); 01315 01316 // increment pointers to the next values 01317 src0 += step; 01318 src1 += step; 01319 dst0 += step; 01320 dst1 += step; 01321 dst2 += step; 01322 } else { 01323 for (; dst0<dstLEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2) { 01324 // convert 1 value 01325 (*subMethod)(src0, src1, dst0, dst1, dst2); 01326 } 01327 01328 // move all pointers to the next line 01329 dstLEnd += dstWidth; 01330 dstSSEEnd += dstWidth; 01331 src0 += srcOffset; 01332 src1 += srcOffset; 01333 dst0 += dstOffset; 01334 dst1 += dstOffset; 01335 dst2 += dstOffset; 01336 } 01337 } 01338 } 01339 01340 template<class S, class D> 01341 inline void sse_for(const S *src0, const S *src1, 01342 D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd, 01343 long srcWidth, long dstWidth, long lineWidth, 01344 void (*subMethod)(const S*, const S*, D*, D*, D*, D*), 01345 void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*), 01346 long step) { 01347 D *dstLEnd = dst0 + lineWidth; 01348 D *dstSSEEnd = dstLEnd - (step - 1); 01349 long srcOffset = srcWidth - lineWidth; 01350 long dstOffset = dstWidth - lineWidth; 01351 01352 for (; dst0<dstEnd;) { 01353 if (dst0<dstSSEEnd) { 01354 // convert 'rvalues' values at the same time 01355 (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3); 01356 01357 // increment pointers to the next values 01358 src0 += step; 01359 src1 += step; 01360 dst0 += step; 01361 dst1 += step; 01362 dst2 += step; 01363 dst3 += step; 01364 } else { 01365 for (; dst0<dstLEnd; ++src0, ++src1, ++dst0, ++dst1, ++dst2, ++dst3) { 01366 // convert 1 value 01367 (*subMethod)(src0, src1, dst0, dst1, dst2, dst3); 01368 } 01369 01370 // move all pointers to the next line 01371 dstLEnd += dstWidth; 01372 dstSSEEnd += dstWidth; 01373 src0 += srcOffset; 01374 src1 += srcOffset; 01375 dst0 += dstOffset; 01376 dst1 += dstOffset; 01377 dst2 += dstOffset; 01378 dst3 += dstOffset; 01379 } 01380 } 01381 } 01382 01383 template<class S, class D> 01384 inline void sse_for(const S *src0, const S *src1, const S *src2, 01385 D *dst0, D *dstEnd, 01386 long srcWidth, long dstWidth, long lineWidth, 01387 void (*subMethod)(const S*, const S*, const S*, D*), 01388 void (*subSSEMethod)(const S*, const S*, const S*, D*), 01389 long step) { 01390 D *dstLEnd = dst0 + lineWidth; 01391 D *dstSSEEnd = dstLEnd - (step - 1); 01392 long srcOffset = srcWidth - lineWidth; 01393 long dstOffset = dstWidth - lineWidth; 01394 01395 for (; dst0<dstEnd;) { 01396 if (dst0<dstSSEEnd) { 01397 // convert 'rvalues' values at the same time 01398 (*subSSEMethod)(src0, src1, src2, dst0); 01399 01400 // increment pointers to the next values 01401 src0 += step; 01402 src1 += step; 01403 src2 += step; 01404 dst0 += step; 01405 } else { 01406 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0) { 01407 // convert 1 value 01408 (*subMethod)(src0, src1, src2, dst0); 01409 } 01410 01411 // move all pointers to the next line 01412 dstLEnd += dstWidth; 01413 dstSSEEnd += dstWidth; 01414 src0 += srcOffset; 01415 src1 += srcOffset; 01416 src2 += srcOffset; 01417 dst0 += dstOffset; 01418 } 01419 } 01420 } 01421 01422 template<class S, class D> 01423 inline void sse_for(const S *src0, const S *src1, const S *src2, 01424 D *dst0, D *dst1, D *dstEnd, 01425 long srcWidth, long dstWidth, long lineWidth, 01426 void (*subMethod)(const S*, const S*, const S*, D*, D*), 01427 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*), 01428 long step) { 01429 D *dstLEnd = dst0 + lineWidth; 01430 D *dstSSEEnd = dstLEnd - (step - 1); 01431 long srcOffset = srcWidth - lineWidth; 01432 long dstOffset = dstWidth - lineWidth; 01433 01434 for (; dst0<dstEnd;) { 01435 if (dst0<dstSSEEnd) { 01436 // convert 'rvalues' values at the same time 01437 (*subSSEMethod)(src0, src1, src2, dst0, dst1); 01438 01439 // increment pointers to the next values 01440 src0 += step; 01441 src1 += step; 01442 src2 += step; 01443 dst0 += step; 01444 dst1 += step; 01445 } else { 01446 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1) { 01447 // convert 1 value 01448 (*subMethod)(src0, src1, src2, dst0, dst1); 01449 } 01450 01451 // move all pointers to the next line 01452 dstLEnd += dstWidth; 01453 dstSSEEnd += dstWidth; 01454 src0 += srcOffset; 01455 src1 += srcOffset; 01456 src2 += srcOffset; 01457 dst0 += dstOffset; 01458 dst1 += dstOffset; 01459 } 01460 } 01461 } 01462 01463 template<class S, class D> 01464 inline void sse_for(const S *src0, const S *src1, const S *src2, 01465 D *dst0, D *dst1, D *dst2, D *dstEnd, 01466 long srcWidth, long dstWidth, long lineWidth, 01467 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*), 01468 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*), 01469 long step) { 01470 D *dstLEnd = dst0 + lineWidth; 01471 D *dstSSEEnd = dstLEnd - (step - 1); 01472 long srcOffset = srcWidth - lineWidth; 01473 long dstOffset = dstWidth - lineWidth; 01474 01475 for (; dst0<dstEnd;) { 01476 if (dst0<dstSSEEnd) { 01477 // convert 'rvalues' values at the same time 01478 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2); 01479 01480 // increment pointers to the next values 01481 src0 += step; 01482 src1 += step; 01483 src2 += step; 01484 dst0 += step; 01485 dst1 += step; 01486 dst2 += step; 01487 } else { 01488 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2) { 01489 // convert 1 value 01490 (*subMethod)(src0, src1, src2, dst0, dst1, dst2); 01491 } 01492 01493 // move all pointers to the next line 01494 dstLEnd += dstWidth; 01495 dstSSEEnd += dstWidth; 01496 src0 += srcOffset; 01497 src1 += srcOffset; 01498 src2 += srcOffset; 01499 dst0 += dstOffset; 01500 dst1 += dstOffset; 01501 dst2 += dstOffset; 01502 } 01503 } 01504 } 01505 01506 template<class S, class D> 01507 inline void sse_for(const S *src0, const S *src1, const S *src2, 01508 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 01509 long srcWidth, long dstWidth, long lineWidth, 01510 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 01511 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 01512 long step) { 01513 D *dstLEnd = dst0 + lineWidth; 01514 D *dstSSEEnd = dstLEnd - (step - 1); 01515 long srcOffset = srcWidth - lineWidth; 01516 long dstOffset = dstWidth - lineWidth; 01517 01518 for (; dst0<dstEnd;) { 01519 if (dst0<dstSSEEnd) { 01520 // convert 'rvalues' values at the same time 01521 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 01522 01523 // increment pointers to the next values 01524 src0 += step; 01525 src1 += step; 01526 src2 += step; 01527 dst0 += step; 01528 dst1 += step; 01529 dst2 += step; 01530 dst3 += step; 01531 } else { 01532 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++dst0, ++dst1, ++dst2, ++dst3) { 01533 // convert 1 value 01534 (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 01535 } 01536 01537 // move all pointers to the next line 01538 dstLEnd += dstWidth; 01539 dstSSEEnd += dstWidth; 01540 src0 += srcOffset; 01541 src1 += srcOffset; 01542 src2 += srcOffset; 01543 dst0 += dstOffset; 01544 dst1 += dstOffset; 01545 dst2 += dstOffset; 01546 dst3 += dstOffset; 01547 } 01548 } 01549 } 01550 01551 template<class S, class D> 01552 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 01553 D *dst0, D *dstEnd, 01554 long srcWidth, long dstWidth, long lineWidth, 01555 void (*subMethod)(const S*, const S*, const S*, const S*, D*), 01556 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*), 01557 long step) { 01558 D *dstLEnd = dst0 + lineWidth; 01559 D *dstSSEEnd = dstLEnd - (step - 1); 01560 long srcOffset = srcWidth - lineWidth; 01561 long dstOffset = dstWidth - lineWidth; 01562 01563 for (; dst0<dstEnd;) { 01564 if (dst0<dstSSEEnd) { 01565 // convert 'rvalues' values at the same time 01566 (*subSSEMethod)(src0, src1, src2, src3, dst0); 01567 01568 // increment pointers to the next values 01569 src0 += step; 01570 src1 += step; 01571 src2 += step; 01572 src3 += step; 01573 dst0 += step; 01574 } else { 01575 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0) { 01576 // convert 1 value 01577 (*subMethod)(src0, src1, src2, src3, dst0); 01578 } 01579 01580 // move all pointers to the next line 01581 dstLEnd += dstWidth; 01582 dstSSEEnd += dstWidth; 01583 src0 += srcOffset; 01584 src1 += srcOffset; 01585 src2 += srcOffset; 01586 src3 += srcOffset; 01587 dst0 += dstOffset; 01588 } 01589 } 01590 } 01591 01592 template<class S, class D> 01593 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 01594 D *dst0, D *dst1, D *dstEnd, 01595 long srcWidth, long dstWidth, long lineWidth, 01596 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*), 01597 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*), 01598 long step) { 01599 D *dstLEnd = dst0 + lineWidth; 01600 D *dstSSEEnd = dstLEnd - (step - 1); 01601 long srcOffset = srcWidth - lineWidth; 01602 long dstOffset = dstWidth - lineWidth; 01603 01604 for (; dst0<dstEnd;) { 01605 if (dst0<dstSSEEnd) { 01606 // convert 'rvalues' values at the same time 01607 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1); 01608 01609 // increment pointers to the next values 01610 src0 += step; 01611 src1 += step; 01612 src2 += step; 01613 src3 += step; 01614 dst0 += step; 01615 dst1 += step; 01616 } else { 01617 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1) { 01618 // convert 1 value 01619 (*subMethod)(src0, src1, src2, src3, dst0, dst1); 01620 } 01621 01622 // move all pointers to the next line 01623 dstLEnd += dstWidth; 01624 dstSSEEnd += dstWidth; 01625 src0 += srcOffset; 01626 src1 += srcOffset; 01627 src2 += srcOffset; 01628 src3 += srcOffset; 01629 dst0 += dstOffset; 01630 dst1 += dstOffset; 01631 } 01632 } 01633 } 01634 01635 template<class S, class D> 01636 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 01637 D *dst0, D *dst1, D *dst2, D *dstEnd, 01638 long srcWidth, long dstWidth, long lineWidth, 01639 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 01640 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 01641 long step) { 01642 D *dstLEnd = dst0 + lineWidth; 01643 D *dstSSEEnd = dstLEnd - (step - 1); 01644 long srcOffset = srcWidth - lineWidth; 01645 long dstOffset = dstWidth - lineWidth; 01646 01647 for (; dst0<dstEnd;) { 01648 if (dst0<dstSSEEnd) { 01649 // convert 'rvalues' values at the same time 01650 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 01651 01652 // increment pointers to the next values 01653 src0 += step; 01654 src1 += step; 01655 src2 += step; 01656 src3 += step; 01657 dst0 += step; 01658 dst1 += step; 01659 dst2 += step; 01660 } else { 01661 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2) { 01662 // convert 1 value 01663 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 01664 } 01665 01666 // move all pointers to the next line 01667 dstLEnd += dstWidth; 01668 dstSSEEnd += dstWidth; 01669 src0 += srcOffset; 01670 src1 += srcOffset; 01671 src2 += srcOffset; 01672 src3 += srcOffset; 01673 dst0 += dstOffset; 01674 dst1 += dstOffset; 01675 dst2 += dstOffset; 01676 } 01677 } 01678 } 01679 01680 template<class S, class D> 01681 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 01682 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 01683 long srcWidth, long dstWidth, long lineWidth, 01684 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 01685 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 01686 long step) { 01687 D *dstLEnd = dst0 + lineWidth; 01688 D *dstSSEEnd = dstLEnd - (step - 1); 01689 long srcOffset = srcWidth - lineWidth; 01690 long dstOffset = dstWidth - lineWidth; 01691 01692 for (; dst0<dstEnd;) { 01693 if (dst0<dstSSEEnd) { 01694 // convert 'rvalues' values at the same time 01695 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 01696 01697 // increment pointers to the next values 01698 src0 += step; 01699 src1 += step; 01700 src2 += step; 01701 src3 += step; 01702 dst0 += step; 01703 dst1 += step; 01704 dst2 += step; 01705 dst3 += step; 01706 } else { 01707 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++dst0, ++dst1, ++dst2, ++dst3) { 01708 // convert 1 value 01709 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 01710 } 01711 01712 // move all pointers to the next line 01713 dstLEnd += dstWidth; 01714 dstSSEEnd += dstWidth; 01715 src0 += srcOffset; 01716 src1 += srcOffset; 01717 src2 += srcOffset; 01718 src3 += srcOffset; 01719 dst0 += dstOffset; 01720 dst1 += dstOffset; 01721 dst2 += dstOffset; 01722 dst3 += dstOffset; 01723 } 01724 } 01725 } 01726 01727 template<class S, class D> 01728 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, const S *src4, 01729 D *dst0, D *dstEnd, 01730 long srcWidth, long dstWidth, long lineWidth, 01731 void (*subMethod)(const S*, const S*, const S*, const S*, const S*, D*), 01732 void (*subSSEMethod)(const S*, const S*, const S*, const S*, const S*, D*), 01733 long step) { 01734 D *dstLEnd = dst0 + lineWidth; 01735 D *dstSSEEnd = dstLEnd - (step - 1); 01736 long srcOffset = srcWidth - lineWidth; 01737 long dstOffset = dstWidth - lineWidth; 01738 01739 for (; dst0<dstEnd;) { 01740 if (dst0<dstSSEEnd) { 01741 // convert 'rvalues' values at the same time 01742 (*subSSEMethod)(src0, src1, src2, src3, src4, dst0); 01743 01744 // increment pointers to the next values 01745 src0 += step; 01746 src1 += step; 01747 src2 += step; 01748 src3 += step; 01749 src4 += step; 01750 dst0 += step; 01751 } else { 01752 for (; dst0<dstLEnd; ++src0, ++src1, ++src2, ++src3, ++src4, ++dst0) { 01753 // convert 1 value 01754 (*subMethod)(src0, src1, src2, src3, src4, dst0); 01755 } 01756 01757 // move all pointers to the next line 01758 dstLEnd += dstWidth; 01759 dstSSEEnd += dstWidth; 01760 src0 += srcOffset; 01761 src1 += srcOffset; 01762 src2 += srcOffset; 01763 src3 += srcOffset; 01764 src4 += srcOffset; 01765 dst0 += dstOffset; 01766 } 01767 } 01768 } 01769 01770 // the sse_for functions can be implemented compact in only one function 01771 // using pointer-to-pointer, but it is slower than the current 01772 // implementation of many versions 01773 01774 template<class S, class D> 01775 inline void sse_for(const S *src0, 01776 D *dst0, D *dstEnd, 01777 long srcWidth, long dstWidth, long lineWidth, 01778 void (*subMethod)(const S*, D*), 01779 void (*subSSEMethod)(const S*, D*), 01780 long srcStep, long dstStep) { 01781 D *dstLEnd = dst0 + lineWidth; 01782 D *dstSSEEnd = dstLEnd - (dstStep - 1); 01783 long srcOffset = srcWidth - lineWidth; 01784 long dstOffset = dstWidth - lineWidth; 01785 long sStep, dStep; 01786 01787 if (srcStep < dstStep) { 01788 dStep = dstStep / srcStep; 01789 sStep = 1; 01790 } else { 01791 sStep = srcStep / dstStep; 01792 dStep = 1; 01793 } 01794 01795 for (; dst0<dstEnd;) { 01796 if (dst0<dstSSEEnd) { 01797 // convert 'rvalues' values at the same time 01798 (*subSSEMethod)(src0, dst0); 01799 01800 // increment pointers to the next values 01801 src0 += srcStep; 01802 dst0 += dstStep; 01803 } else { 01804 for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep) { 01805 // convert 1 value 01806 (*subMethod)(src0, dst0); 01807 } 01808 01809 // move all pointers to the next line 01810 dstLEnd += dstWidth; 01811 dstSSEEnd += dstWidth; 01812 src0 += srcOffset; 01813 dst0 += dstOffset; 01814 } 01815 } 01816 } 01817 01818 template<class S, class D> 01819 inline void sse_for(const S *src0, 01820 D *dst0, D *dst1, D *dstEnd, 01821 long srcWidth, long dstWidth, long lineWidth, 01822 void (*subMethod)(const S*, D*, D*), 01823 void (*subSSEMethod)(const S*, D*, D*), 01824 long srcStep, long dstStep) { 01825 D *dstLEnd = dst0 + lineWidth; 01826 D *dstSSEEnd = dstLEnd - (dstStep - 1); 01827 long srcOffset = srcWidth - lineWidth; 01828 long dstOffset = dstWidth - lineWidth; 01829 long sStep, dStep; 01830 01831 if (srcStep < dstStep) { 01832 dStep = dstStep / srcStep; 01833 sStep = 1; 01834 } else { 01835 sStep = srcStep / dstStep; 01836 dStep = 1; 01837 } 01838 01839 for (; dst0<dstEnd;) { 01840 if (dst0<dstSSEEnd) { 01841 // convert 'rvalues' values at the same time 01842 (*subSSEMethod)(src0, dst0, dst1); 01843 01844 // increment pointers to the next values 01845 src0 += srcStep; 01846 dst0 += dstStep; 01847 dst1 += dstStep; 01848 } else { 01849 for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep, dst1 += dStep) { 01850 // convert 1 value 01851 (*subMethod)(src0, dst0, dst1); 01852 } 01853 01854 // move all pointers to the next line 01855 dstLEnd += dstWidth; 01856 dstSSEEnd += dstWidth; 01857 src0 += srcOffset; 01858 dst0 += dstOffset; 01859 dst1 += dstOffset; 01860 } 01861 } 01862 } 01863 01864 template<class S, class D> 01865 inline void sse_for(const S *src0, 01866 D *dst0, D *dst1, D *dst2, D *dstEnd, 01867 long srcWidth, long dstWidth, long lineWidth, 01868 void (*subMethod)(const S*, D*, D*, D*), 01869 void (*subSSEMethod)(const S*, D*, D*, D*), 01870 long srcStep, long dstStep) { 01871 D *dstLEnd = dst0 + lineWidth; 01872 D *dstSSEEnd = dstLEnd - (dstStep - 1); 01873 long srcOffset = srcWidth - lineWidth; 01874 long dstOffset = dstWidth - lineWidth; 01875 long sStep, dStep; 01876 01877 if (srcStep < dstStep) { 01878 dStep = dstStep / srcStep; 01879 sStep = 1; 01880 } else { 01881 sStep = srcStep / dstStep; 01882 dStep = 1; 01883 } 01884 01885 for (; dst0<dstEnd;) { 01886 if (dst0<dstSSEEnd) { 01887 // convert 'rvalues' values at the same time 01888 (*subSSEMethod)(src0, dst0, dst1, dst2); 01889 01890 // increment pointers to the next values 01891 src0 += srcStep; 01892 dst0 += dstStep; 01893 dst1 += dstStep; 01894 dst2 += dstStep; 01895 } else { 01896 for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 01897 // convert 1 value 01898 (*subMethod)(src0, dst0, dst1, dst2); 01899 } 01900 01901 // move all pointers to the next line 01902 dstLEnd += dstWidth; 01903 dstSSEEnd += dstWidth; 01904 src0 += srcOffset; 01905 dst0 += dstOffset; 01906 dst1 += dstOffset; 01907 dst2 += dstOffset; 01908 } 01909 } 01910 } 01911 01912 template<class S, class D> 01913 inline void sse_for(const S *src0, 01914 D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd, 01915 long srcWidth, long dstWidth, long lineWidth, 01916 void (*subMethod)(const S*, D*, D*, D*, D*), 01917 void (*subSSEMethod)(const S*, D*, D*, D*, D*), 01918 long srcStep, long dstStep) { 01919 D *dstLEnd = dst0 + lineWidth; 01920 D *dstSSEEnd = dstLEnd - (dstStep - 1); 01921 long srcOffset = srcWidth - lineWidth; 01922 long dstOffset = dstWidth - lineWidth; 01923 long sStep, dStep; 01924 01925 if (srcStep < dstStep) { 01926 dStep = dstStep / srcStep; 01927 sStep = 1; 01928 } else { 01929 sStep = srcStep / dstStep; 01930 dStep = 1; 01931 } 01932 01933 for (; dst0<dstEnd;) { 01934 if (dst0<dstSSEEnd) { 01935 // convert 'rvalues' values at the same time 01936 (*subSSEMethod)(src0, dst0, dst1, dst2, dst3); 01937 01938 // increment pointers to the next values 01939 src0 += srcStep; 01940 dst0 += dstStep; 01941 dst1 += dstStep; 01942 dst2 += dstStep; 01943 dst3 += dstStep; 01944 } else { 01945 for (; dst0<dstLEnd; src0 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 01946 // convert 1 value 01947 (*subMethod)(src0, dst0, dst1, dst2, dst3); 01948 } 01949 01950 // move all pointers to the next line 01951 dstLEnd += dstWidth; 01952 dstSSEEnd += dstWidth; 01953 src0 += srcOffset; 01954 dst0 += dstOffset; 01955 dst1 += dstOffset; 01956 dst2 += dstOffset; 01957 dst3 += dstOffset; 01958 } 01959 } 01960 } 01961 01962 template<class S, class D> 01963 inline void sse_for(const S *src0, const S *src1, 01964 D *dst0, D *dst1, D *dstEnd, 01965 long srcWidth, long dstWidth, long lineWidth, 01966 void (*subMethod)(const S*, const S*, D*, D*), 01967 void (*subSSEMethod)(const S*, const S*, D*, D*), 01968 long srcStep, long dstStep) { 01969 D *dstLEnd = dst0 + lineWidth; 01970 D *dstSSEEnd = dstLEnd - (dstStep - 1); 01971 long srcOffset = srcWidth - lineWidth; 01972 long dstOffset = dstWidth - lineWidth; 01973 long sStep, dStep; 01974 01975 if (srcStep < dstStep) { 01976 dStep = dstStep / srcStep; 01977 sStep = 1; 01978 } else { 01979 sStep = srcStep / dstStep; 01980 dStep = 1; 01981 } 01982 01983 for (; dst0<dstEnd;) { 01984 if (dst0<dstSSEEnd) { 01985 // convert 'rvalues' values at the same time 01986 (*subSSEMethod)(src0, src1, dst0, dst1); 01987 01988 // increment pointers to the next values 01989 src0 += srcStep; 01990 src1 += srcStep; 01991 dst0 += dstStep; 01992 dst1 += dstStep; 01993 } else { 01994 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep) { 01995 // convert 1 value 01996 (*subMethod)(src0, src1, dst0, dst1); 01997 } 01998 01999 // move all pointers to the next line 02000 dstLEnd += dstWidth; 02001 dstSSEEnd += dstWidth; 02002 src0 += srcOffset; 02003 src1 += srcOffset; 02004 dst0 += dstOffset; 02005 dst1 += dstOffset; 02006 } 02007 } 02008 } 02009 02010 template<class S, class D> 02011 inline void sse_for(const S *src0, const S *src1, 02012 D *dst0, D *dst1, D *dst2, D *dstEnd, 02013 long srcWidth, long dstWidth, long lineWidth, 02014 void (*subMethod)(const S*, const S*, D*, D*, D*), 02015 void (*subSSEMethod)(const S*, const S*, D*, D*, D*), 02016 long srcStep, long dstStep) { 02017 D *dstLEnd = dst0 + lineWidth; 02018 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02019 long srcOffset = srcWidth - lineWidth; 02020 long dstOffset = dstWidth - lineWidth; 02021 long sStep, dStep; 02022 02023 if (srcStep < dstStep) { 02024 dStep = dstStep / srcStep; 02025 sStep = 1; 02026 } else { 02027 sStep = srcStep / dstStep; 02028 dStep = 1; 02029 } 02030 02031 for (; dst0<dstEnd;) { 02032 if (dst0<dstSSEEnd) { 02033 // convert 'rvalues' values at the same time 02034 (*subSSEMethod)(src0, src1, dst0, dst1, dst2); 02035 02036 // increment pointers to the next values 02037 src0 += srcStep; 02038 src1 += srcStep; 02039 dst0 += dstStep; 02040 dst1 += dstStep; 02041 dst2 += dstStep; 02042 } else { 02043 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 02044 // convert 1 value 02045 (*subMethod)(src0, src1, dst0, dst1, dst2); 02046 } 02047 02048 // move all pointers to the next line 02049 dstLEnd += dstWidth; 02050 dstSSEEnd += dstWidth; 02051 src0 += srcOffset; 02052 src1 += srcOffset; 02053 dst0 += dstOffset; 02054 dst1 += dstOffset; 02055 dst2 += dstOffset; 02056 } 02057 } 02058 } 02059 02060 template<class S, class D> 02061 inline void sse_for(const S *src0, const S *src1, 02062 D *dst0, D *dst1, D *dst2, D *dst3, D *dstEnd, 02063 long srcWidth, long dstWidth, long lineWidth, 02064 void (*subMethod)(const S*, const S*, D*, D*, D*, D*), 02065 void (*subSSEMethod)(const S*, const S*, D*, D*, D*, D*), 02066 long srcStep, long dstStep) { 02067 D *dstLEnd = dst0 + lineWidth; 02068 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02069 long srcOffset = srcWidth - lineWidth; 02070 long dstOffset = dstWidth - lineWidth; 02071 long sStep, dStep; 02072 02073 if (srcStep < dstStep) { 02074 dStep = dstStep / srcStep; 02075 sStep = 1; 02076 } else { 02077 sStep = srcStep / dstStep; 02078 dStep = 1; 02079 } 02080 02081 for (; dst0<dstEnd;) { 02082 if (dst0<dstSSEEnd) { 02083 // convert 'rvalues' values at the same time 02084 (*subSSEMethod)(src0, src1, dst0, dst1, dst2, dst3); 02085 02086 // increment pointers to the next values 02087 src0 += srcStep; 02088 src1 += srcStep; 02089 dst0 += dstStep; 02090 dst1 += dstStep; 02091 dst2 += dstStep; 02092 dst3 += dstStep; 02093 } else { 02094 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 02095 // convert 1 value 02096 (*subMethod)(src0, src1, dst0, dst1, dst2, dst3); 02097 } 02098 02099 // move all pointers to the next line 02100 dstLEnd += dstWidth; 02101 dstSSEEnd += dstWidth; 02102 src0 += srcOffset; 02103 src1 += srcOffset; 02104 dst0 += dstOffset; 02105 dst1 += dstOffset; 02106 dst2 += dstOffset; 02107 dst3 += dstOffset; 02108 } 02109 } 02110 } 02111 02112 template<class S, class D> 02113 inline void sse_for(const S *src0, const S *src1, const S *src2, 02114 D *dst0, D *dstEnd, 02115 long srcWidth, long dstWidth, long lineWidth, 02116 void (*subMethod)(const S*, const S*, const S*, D*), 02117 void (*subSSEMethod)(const S*, const S*, const S*, D*), 02118 long srcStep, long dstStep) { 02119 D *dstLEnd = dst0 + lineWidth; 02120 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02121 long srcOffset = srcWidth - lineWidth; 02122 long dstOffset = dstWidth - lineWidth; 02123 long sStep, dStep; 02124 02125 if (srcStep < dstStep) { 02126 dStep = dstStep / srcStep; 02127 sStep = 1; 02128 } else { 02129 sStep = srcStep / dstStep; 02130 dStep = 1; 02131 } 02132 02133 for (; dst0<dstEnd;) { 02134 if (dst0<dstSSEEnd) { 02135 // convert 'rvalues' values at the same time 02136 (*subSSEMethod)(src0, src1, src2, dst0); 02137 02138 // increment pointers to the next values 02139 src0 += srcStep; 02140 src1 += srcStep; 02141 src2 += srcStep; 02142 dst0 += dstStep; 02143 } else { 02144 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep) { 02145 // convert 1 value 02146 (*subMethod)(src0, src1, src2, dst0); 02147 } 02148 02149 // move all pointers to the next line 02150 dstLEnd += dstWidth; 02151 dstSSEEnd += dstWidth; 02152 src0 += srcOffset; 02153 src1 += srcOffset; 02154 src2 += srcOffset; 02155 dst0 += dstOffset; 02156 } 02157 } 02158 } 02159 02160 template<class S, class D> 02161 inline void sse_for(const S *src0, const S *src1, const S *src2, 02162 D *dst0, D *dst1, D *dstEnd, 02163 long srcWidth, long dstWidth, long lineWidth, 02164 void (*subMethod)(const S*, const S*, const S*, D*, D*), 02165 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*), 02166 long srcStep, long dstStep) { 02167 D *dstLEnd = dst0 + lineWidth; 02168 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02169 long srcOffset = srcWidth - lineWidth; 02170 long dstOffset = dstWidth - lineWidth; 02171 long sStep, dStep; 02172 02173 if (srcStep < dstStep) { 02174 dStep = dstStep / srcStep; 02175 sStep = 1; 02176 } else { 02177 sStep = srcStep / dstStep; 02178 dStep = 1; 02179 } 02180 02181 for (; dst0<dstEnd;) { 02182 if (dst0<dstSSEEnd) { 02183 // convert 'rvalues' values at the same time 02184 (*subSSEMethod)(src0, src1, src2, dst0, dst1); 02185 02186 // increment pointers to the next values 02187 src0 += srcStep; 02188 src1 += srcStep; 02189 src2 += srcStep; 02190 dst0 += dstStep; 02191 dst1 += dstStep; 02192 } else { 02193 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep) { 02194 // convert 1 value 02195 (*subMethod)(src0, src1, src2, dst0, dst1); 02196 } 02197 02198 // move all pointers to the next line 02199 dstLEnd += dstWidth; 02200 dstSSEEnd += dstWidth; 02201 src0 += srcOffset; 02202 src1 += srcOffset; 02203 src2 += srcOffset; 02204 dst0 += dstOffset; 02205 dst1 += dstOffset; 02206 } 02207 } 02208 } 02209 02210 template<class S, class D> 02211 inline void sse_for(const S *src0, const S *src1, const S *src2, 02212 D *dst0, D *dst1, D *dst2, D *dstEnd, 02213 long srcWidth, long dstWidth, long lineWidth, 02214 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*), 02215 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*), 02216 long srcStep, long dstStep) { 02217 D *dstLEnd = dst0 + lineWidth; 02218 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02219 long srcOffset = srcWidth - lineWidth; 02220 long dstOffset = dstWidth - lineWidth; 02221 long sStep, dStep; 02222 02223 if (srcStep < dstStep) { 02224 dStep = dstStep / srcStep; 02225 sStep = 1; 02226 } else { 02227 sStep = srcStep / dstStep; 02228 dStep = 1; 02229 } 02230 02231 for (; dst0<dstEnd;) { 02232 if (dst0<dstSSEEnd) { 02233 // convert 'rvalues' values at the same time 02234 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2); 02235 02236 // increment pointers to the next values 02237 src0 += srcStep; 02238 src1 += srcStep; 02239 src2 += srcStep; 02240 dst0 += dstStep; 02241 dst1 += dstStep; 02242 dst2 += dstStep; 02243 } else { 02244 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 02245 // convert 1 value 02246 (*subMethod)(src0, src1, src2, dst0, dst1, dst2); 02247 } 02248 02249 // move all pointers to the next line 02250 dstLEnd += dstWidth; 02251 dstSSEEnd += dstWidth; 02252 src0 += srcOffset; 02253 src1 += srcOffset; 02254 src2 += srcOffset; 02255 dst0 += dstOffset; 02256 dst1 += dstOffset; 02257 dst2 += dstOffset; 02258 } 02259 } 02260 } 02261 02262 template<class S, class D> 02263 inline void sse_for(const S *src0, const S *src1, const S *src2, 02264 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 02265 long srcWidth, long dstWidth, long lineWidth, 02266 void (*subMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 02267 void (*subSSEMethod)(const S*, const S*, const S*, D*, D*, D*, D*), 02268 long srcStep, long dstStep) { 02269 D *dstLEnd = dst0 + lineWidth; 02270 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02271 long srcOffset = srcWidth - lineWidth; 02272 long dstOffset = dstWidth - lineWidth; 02273 long sStep, dStep; 02274 02275 if (srcStep < dstStep) { 02276 dStep = dstStep / srcStep; 02277 sStep = 1; 02278 } else { 02279 sStep = srcStep / dstStep; 02280 dStep = 1; 02281 } 02282 02283 for (; dst0<dstEnd;) { 02284 if (dst0<dstSSEEnd) { 02285 // convert 'rvalues' values at the same time 02286 (*subSSEMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 02287 02288 // increment pointers to the next values 02289 src0 += srcStep; 02290 src1 += srcStep; 02291 src2 += srcStep; 02292 dst0 += dstStep; 02293 dst1 += dstStep; 02294 dst2 += dstStep; 02295 dst3 += dstStep; 02296 } else { 02297 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 02298 // convert 1 value 02299 (*subMethod)(src0, src1, src2, dst0, dst1, dst2, dst3); 02300 } 02301 02302 // move all pointers to the next line 02303 dstLEnd += dstWidth; 02304 dstSSEEnd += dstWidth; 02305 src0 += srcOffset; 02306 src1 += srcOffset; 02307 src2 += srcOffset; 02308 dst0 += dstOffset; 02309 dst1 += dstOffset; 02310 dst2 += dstOffset; 02311 dst3 += dstOffset; 02312 } 02313 } 02314 } 02315 02316 template<class S, class D> 02317 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 02318 D *dst0, D *dstEnd, 02319 long srcWidth, long dstWidth, long lineWidth, 02320 void (*subMethod)(const S*, const S*, const S*, const S*, D*), 02321 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*), 02322 long srcStep, long dstStep) { 02323 D *dstLEnd = dst0 + lineWidth; 02324 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02325 long srcOffset = srcWidth - lineWidth; 02326 long dstOffset = dstWidth - lineWidth; 02327 long sStep, dStep; 02328 02329 if (srcStep < dstStep) { 02330 dStep = dstStep / srcStep; 02331 sStep = 1; 02332 } else { 02333 sStep = srcStep / dstStep; 02334 dStep = 1; 02335 } 02336 02337 for (; dst0<dstEnd;) { 02338 if (dst0<dstSSEEnd) { 02339 // convert 'rvalues' values at the same time 02340 (*subSSEMethod)(src0, src1, src2, src3, dst0); 02341 02342 // increment pointers to the next values 02343 src0 += srcStep; 02344 src1 += srcStep; 02345 src2 += srcStep; 02346 src3 += srcStep; 02347 dst0 += dstStep; 02348 } else { 02349 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep) { 02350 // convert 1 value 02351 (*subMethod)(src0, src1, src2, src3, dst0); 02352 } 02353 02354 // move all pointers to the next line 02355 dstLEnd += dstWidth; 02356 dstSSEEnd += dstWidth; 02357 src0 += srcOffset; 02358 src1 += srcOffset; 02359 src2 += srcOffset; 02360 src3 += srcOffset; 02361 dst0 += dstOffset; 02362 } 02363 } 02364 } 02365 02366 template<class S, class D> 02367 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 02368 D *dst0, D *dst1, D *dstEnd, 02369 long srcWidth, long dstWidth, long lineWidth, 02370 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*), 02371 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*), 02372 long srcStep, long dstStep) { 02373 D *dstLEnd = dst0 + lineWidth; 02374 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02375 long srcOffset = srcWidth - lineWidth; 02376 long dstOffset = dstWidth - lineWidth; 02377 long sStep, dStep; 02378 02379 if (srcStep < dstStep) { 02380 dStep = dstStep / srcStep; 02381 sStep = 1; 02382 } else { 02383 sStep = srcStep / dstStep; 02384 dStep = 1; 02385 } 02386 02387 for (; dst0<dstEnd;) { 02388 if (dst0<dstSSEEnd) { 02389 // convert 'rvalues' values at the same time 02390 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1); 02391 02392 // increment pointers to the next values 02393 src0 += srcStep; 02394 src1 += srcStep; 02395 src2 += srcStep; 02396 src3 += srcStep; 02397 dst0 += dstStep; 02398 dst1 += dstStep; 02399 } else { 02400 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep) { 02401 // convert 1 value 02402 (*subMethod)(src0, src1, src2, src3, dst0, dst1); 02403 } 02404 02405 // move all pointers to the next line 02406 dstLEnd += dstWidth; 02407 dstSSEEnd += dstWidth; 02408 src0 += srcOffset; 02409 src1 += srcOffset; 02410 src2 += srcOffset; 02411 src3 += srcOffset; 02412 dst0 += dstOffset; 02413 dst1 += dstOffset; 02414 } 02415 } 02416 } 02417 02418 template<class S, class D> 02419 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 02420 D *dst0, D *dst1, D *dst2, D *dstEnd, 02421 long srcWidth, long dstWidth, long lineWidth, 02422 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 02423 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*), 02424 long srcStep, long dstStep) { 02425 D *dstLEnd = dst0 + lineWidth; 02426 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02427 long srcOffset = srcWidth - lineWidth; 02428 long dstOffset = dstWidth - lineWidth; 02429 long sStep, dStep; 02430 02431 if (srcStep < dstStep) { 02432 dStep = dstStep / srcStep; 02433 sStep = 1; 02434 } else { 02435 sStep = srcStep / dstStep; 02436 dStep = 1; 02437 } 02438 02439 for (; dst0<dstEnd;) { 02440 if (dst0<dstSSEEnd) { 02441 // convert 'rvalues' values at the same time 02442 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 02443 02444 // increment pointers to the next values 02445 src0 += srcStep; 02446 src1 += srcStep; 02447 src2 += srcStep; 02448 src3 += srcStep; 02449 dst0 += dstStep; 02450 dst1 += dstStep; 02451 dst2 += dstStep; 02452 } else { 02453 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep) { 02454 // convert 1 value 02455 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2); 02456 } 02457 02458 // move all pointers to the next line 02459 dstLEnd += dstWidth; 02460 dstSSEEnd += dstWidth; 02461 src0 += srcOffset; 02462 src1 += srcOffset; 02463 src2 += srcOffset; 02464 src3 += srcOffset; 02465 dst0 += dstOffset; 02466 dst1 += dstOffset; 02467 dst2 += dstOffset; 02468 } 02469 } 02470 } 02471 02472 template<class S, class D> 02473 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, 02474 D *dst0, D *dst1, D *dst2, D* dst3, D *dstEnd, 02475 long srcWidth, long dstWidth, long lineWidth, 02476 void (*subMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 02477 void (*subSSEMethod)(const S*, const S*, const S*, const S*, D*, D*, D*, D*), 02478 long srcStep, long dstStep) { 02479 D *dstLEnd = dst0 + lineWidth; 02480 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02481 long srcOffset = srcWidth - lineWidth; 02482 long dstOffset = dstWidth - lineWidth; 02483 long sStep, dStep; 02484 02485 if (srcStep < dstStep) { 02486 dStep = dstStep / srcStep; 02487 sStep = 1; 02488 } else { 02489 sStep = srcStep / dstStep; 02490 dStep = 1; 02491 } 02492 02493 for (; dst0<dstEnd;) { 02494 if (dst0<dstSSEEnd) { 02495 // convert 'rvalues' values at the same time 02496 (*subSSEMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 02497 02498 // increment pointers to the next values 02499 src0 += srcStep; 02500 src1 += srcStep; 02501 src2 += srcStep; 02502 src3 += srcStep; 02503 dst0 += dstStep; 02504 dst1 += dstStep; 02505 dst2 += dstStep; 02506 dst3 += dstStep; 02507 } else { 02508 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, dst0 += dStep, dst1 += dStep, dst2 += dStep, dst3 += dStep) { 02509 // convert 1 value 02510 (*subMethod)(src0, src1, src2, src3, dst0, dst1, dst2, dst3); 02511 } 02512 02513 // move all pointers to the next line 02514 dstLEnd += dstWidth; 02515 dstSSEEnd += dstWidth; 02516 src0 += srcOffset; 02517 src1 += srcOffset; 02518 src2 += srcOffset; 02519 src3 += srcOffset; 02520 dst0 += dstOffset; 02521 dst1 += dstOffset; 02522 dst2 += dstOffset; 02523 dst3 += dstOffset; 02524 } 02525 } 02526 } 02527 02528 template<class S, class D> 02529 inline void sse_for(const S *src0, const S *src1, const S *src2, const S *src3, const S *src4, 02530 D *dst0, D *dstEnd, 02531 long srcWidth, long dstWidth, long lineWidth, 02532 void (*subMethod)(const S*, const S*, const S*, const S*, const S*, D*), 02533 void (*subSSEMethod)(const S*, const S*, const S*, const S*, const S*, D*), 02534 long srcStep, long dstStep) { 02535 D *dstLEnd = dst0 + lineWidth; 02536 D *dstSSEEnd = dstLEnd - (dstStep - 1); 02537 long srcOffset = srcWidth - lineWidth; 02538 long dstOffset = dstWidth - lineWidth; 02539 long sStep, dStep; 02540 02541 if (srcStep < dstStep) { 02542 dStep = dstStep / srcStep; 02543 sStep = 1; 02544 } else { 02545 sStep = srcStep / dstStep; 02546 dStep = 1; 02547 } 02548 02549 for (; dst0<dstEnd;) { 02550 if (dst0<dstSSEEnd) { 02551 // convert 'rvalues' values at the same time 02552 (*subSSEMethod)(src0, src1, src2, src3, src4, dst0); 02553 02554 // increment pointers to the next values 02555 src0 += srcStep; 02556 src1 += srcStep; 02557 src2 += srcStep; 02558 src3 += srcStep; 02559 src4 += srcStep; 02560 dst0 += dstStep; 02561 } else { 02562 for (; dst0<dstLEnd; src0 += sStep, src1 += sStep, src2 += sStep, src3 += sStep, src4 += sStep, dst0 += dStep) { 02563 // convert 1 value 02564 (*subMethod)(src0, src1, src2, src3, src4, dst0); 02565 } 02566 02567 // move all pointers to the next line 02568 dstLEnd += dstWidth; 02569 dstSSEEnd += dstWidth; 02570 src0 += srcOffset; 02571 src1 += srcOffset; 02572 src2 += srcOffset; 02573 src3 += srcOffset; 02574 src4 += srcOffset; 02575 dst0 += dstOffset; 02576 } 02577 } 02578 } 02579 02580 // -- for-loops with ROI -- // 02581 02582 #endif 02583 02584 } // namespace utils 02585 }