| 2405 | |
| 2406 | |
| 2407 | struct BatchDistInvoker : public ParallelLoopBody |
| 2408 | { |
| 2409 | BatchDistInvoker( const Mat& _src1, const Mat& _src2, |
| 2410 | Mat& _dist, Mat& _nidx, int _K, |
| 2411 | const Mat& _mask, int _update, |
| 2412 | BatchDistFunc _func) |
| 2413 | { |
| 2414 | src1 = &_src1; |
| 2415 | src2 = &_src2; |
| 2416 | dist = &_dist; |
| 2417 | nidx = &_nidx; |
| 2418 | K = _K; |
| 2419 | mask = &_mask; |
| 2420 | update = _update; |
| 2421 | func = _func; |
| 2422 | } |
| 2423 | |
| 2424 | void operator()(const Range& range) const |
| 2425 | { |
| 2426 | AutoBuffer<int> buf(src2->rows); |
| 2427 | int* bufptr = buf; |
| 2428 | |
| 2429 | for( int i = range.start; i < range.end; i++ ) |
| 2430 | { |
| 2431 | func(src1->ptr(i), src2->ptr(), src2->step, src2->rows, src2->cols, |
| 2432 | K > 0 ? (uchar*)bufptr : dist->ptr(i), mask->data ? mask->ptr(i) : 0); |
| 2433 | |
| 2434 | if( K > 0 ) |
| 2435 | { |
| 2436 | int* nidxptr = nidx->ptr<int>(i); |
| 2437 | // since positive float's can be compared just like int's, |
| 2438 | // we handle both CV_32S and CV_32F cases with a single branch |
| 2439 | int* distptr = (int*)dist->ptr(i); |
| 2440 | |
| 2441 | int j, k; |
| 2442 | |
| 2443 | for( j = 0; j < src2->rows; j++ ) |
| 2444 | { |
| 2445 | int d = bufptr[j]; |
| 2446 | if( d < distptr[K-1] ) |
| 2447 | { |
| 2448 | for( k = K-2; k >= 0 && distptr[k] > d; k-- ) |
| 2449 | { |
| 2450 | nidxptr[k+1] = nidxptr[k]; |
| 2451 | distptr[k+1] = distptr[k]; |
| 2452 | } |
| 2453 | nidxptr[k+1] = j + update; |
| 2454 | distptr[k+1] = d; |
| 2455 | } |
| 2456 | } |
| 2457 | } |
| 2458 | } |
| 2459 | } |
| 2460 | |
| 2461 | const Mat *src1; |
| 2462 | const Mat *src2; |
| 2463 | Mat *dist; |
| 2464 | Mat *nidx; |