@@ -133,21 +133,22 @@ int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int
133
133
return CV_HAL_ERROR_OK;
134
134
}
135
135
#endif
136
+ #endif
136
137
137
138
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void *, void *, int , IppiSize);
138
139
139
140
template <int channels, typename Type>
140
- bool IPPSetSimple (cv::Scalar value, void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
141
+ bool IPPSetSimple (const double value[ 4 ] , void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
141
142
{
142
143
// CV_INSTRUMENT_REGION_IPP();
143
144
144
145
Type values[channels];
145
146
for ( int i = 0 ; i < channels; i++ )
146
147
values[i] = cv::saturate_cast<Type>(value[i]);
147
- return func ( values, dataPointer, step, size) >= 0 ;
148
+ return CV_INSTRUMENT_FUN_IPP (func, values, dataPointer, step, size) >= 0 ;
148
149
}
149
150
150
- static bool IPPSet (const cv::Scalar & value, void *dataPointer, int step, IppiSize &size, int channels, int depth)
151
+ static bool IPPSet (const double value[ 4 ] , void *dataPointer, int step, IppiSize &size, int channels, int depth)
151
152
{
152
153
// CV_INSTRUMENT_REGION_IPP();
153
154
@@ -248,7 +249,7 @@ class IPPWarpPerspectiveInvoker :
248
249
{
249
250
IppiSize setSize = {dst.cols , range.end - range.start };
250
251
void *dataPointer = dst.ptr (range.start );
251
- if ( !IPPSet ( cv::Scalar ( borderValue[ 0 ], borderValue[ 1 ], borderValue[ 2 ], borderValue[ 3 ]) , dataPointer, (int )dst.step [0 ], setSize, cnn, src.depth () ) )
252
+ if ( !IPPSet ( borderValue, dataPointer, (int )dst.step [0 ], setSize, cnn, src.depth () ) )
252
253
{
253
254
*ok = false ;
254
255
return ;
@@ -364,4 +365,120 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
364
365
return CV_HAL_ERROR_OK;
365
366
}
366
367
#endif
367
- #endif
368
+
369
+ typedef IppStatus (CV_STDCALL *ippiRemap)(const void *pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
370
+ const Ipp32f *pxMap, int xMapStep, const Ipp32f *pyMap, int yMapStep,
371
+ void *pDst, int dstStep, IppiSize dstRoiSize, int interpolation);
372
+
373
+ class IPPRemapInvoker : public cv ::ParallelLoopBody
374
+ {
375
+ public:
376
+ IPPRemapInvoker (int _src_type, const uchar *_src_data, size_t _src_step, int _src_width, int _src_height,
377
+ uchar *_dst_data, size_t _dst_step, int _dst_width, float *_mapx, size_t _mapx_step, float *_mapy,
378
+ size_t _mapy_step, ippiRemap _ippFunc, int _ippInterpolation, int _borderType, const double _borderValue[4 ], bool *_ok) :
379
+ ParallelLoopBody (),
380
+ src_type (_src_type), src(_src_data), src_step(_src_step), src_width(_src_width), src_height(_src_height),
381
+ dst (_dst_data), dst_step(_dst_step), dst_width(_dst_width), mapx(_mapx), mapx_step(_mapx_step), mapy(_mapy),
382
+ mapy_step (_mapy_step), ippFunc(_ippFunc), ippInterpolation(_ippInterpolation), borderType(_borderType), ok(_ok)
383
+ {
384
+ memcpy (this ->borderValue , _borderValue, sizeof (this ->borderValue ));
385
+ *ok = true ;
386
+ }
387
+
388
+ virtual void operator ()(const cv::Range &range) const
389
+ {
390
+ IppiRect srcRoiRect = {0 , 0 , src_width, src_height};
391
+ uchar *dst_roi_data = dst + range.start * dst_step;
392
+ IppiSize dstRoiSize = ippiSize (dst_width, range.size ());
393
+ int depth = CV_MAT_DEPTH (src_type), cn = CV_MAT_CN (src_type);
394
+
395
+ if (borderType == cv::BORDER_CONSTANT &&
396
+ !IPPSet (borderValue, dst_roi_data, (int )dst_step, dstRoiSize, cn, depth))
397
+ {
398
+ *ok = false ;
399
+ return ;
400
+ }
401
+
402
+ if (CV_INSTRUMENT_FUN_IPP (ippFunc, src, {src_width, src_height}, (int )src_step, srcRoiRect,
403
+ mapx, (int )mapx_step, mapy, (int )mapy_step,
404
+ dst_roi_data, (int )dst_step, dstRoiSize, ippInterpolation) < 0 )
405
+ *ok = false ;
406
+ else
407
+ {
408
+ CV_IMPL_ADD (CV_IMPL_IPP | CV_IMPL_MT);
409
+ }
410
+ }
411
+
412
+ private:
413
+ int src_type;
414
+ const uchar *src;
415
+ size_t src_step;
416
+ int src_width, src_height;
417
+ uchar *dst;
418
+ size_t dst_step;
419
+ int dst_width;
420
+ float *mapx;
421
+ size_t mapx_step;
422
+ float *mapy;
423
+ size_t mapy_step;
424
+ ippiRemap ippFunc;
425
+ int ippInterpolation, borderType;
426
+ double borderValue[4 ];
427
+ bool *ok;
428
+ };
429
+
430
+ int ipp_hal_remap32f (int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
431
+ uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
432
+ float *mapx, size_t mapx_step, float *mapy, size_t mapy_step,
433
+ int interpolation, int border_type, const double border_value[4 ])
434
+ {
435
+ if ((interpolation == cv::INTER_LINEAR || interpolation == cv::INTER_CUBIC || interpolation == cv::INTER_NEAREST) &&
436
+ (border_type == cv::BORDER_CONSTANT || border_type == cv::BORDER_TRANSPARENT))
437
+ {
438
+ int ippInterpolation =
439
+ interpolation == cv::INTER_NEAREST ? IPPI_INTER_NN : interpolation == cv::INTER_LINEAR ? IPPI_INTER_LINEAR
440
+ : IPPI_INTER_CUBIC;
441
+
442
+ /* C1 C2 C3 C4 */
443
+ char impl[CV_DEPTH_MAX][4 ][3 ]={{{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}, // 8U
444
+ {{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}, // 8S
445
+ {{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}, // 16U
446
+ {{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}, // 16S
447
+ {{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}, // 32S
448
+ {{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}, // 32F
449
+ {{0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 }}}; // 64F
450
+
451
+ if (impl[CV_TYPE (src_type)][CV_MAT_CN (src_type) - 1 ][interpolation] == 0 )
452
+ {
453
+ return CV_HAL_ERROR_NOT_IMPLEMENTED;
454
+ }
455
+
456
+ ippiRemap ippFunc =
457
+ src_type == CV_8UC1 ? (ippiRemap)ippiRemap_8u_C1R : src_type == CV_8UC3 ? (ippiRemap)ippiRemap_8u_C3R
458
+ : src_type == CV_8UC4 ? (ippiRemap)ippiRemap_8u_C4R
459
+ : src_type == CV_16UC1 ? (ippiRemap)ippiRemap_16u_C1R
460
+ : src_type == CV_16UC3 ? (ippiRemap)ippiRemap_16u_C3R
461
+ : src_type == CV_16UC4 ? (ippiRemap)ippiRemap_16u_C4R
462
+ : src_type == CV_32FC1 ? (ippiRemap)ippiRemap_32f_C1R
463
+ : src_type == CV_32FC3 ? (ippiRemap)ippiRemap_32f_C3R
464
+ : src_type == CV_32FC4 ? (ippiRemap)ippiRemap_32f_C4R
465
+ : 0 ;
466
+
467
+ if (ippFunc)
468
+ {
469
+ bool ok;
470
+
471
+ IPPRemapInvoker invoker (src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width,
472
+ mapx, mapx_step, mapy, mapy_step, ippFunc, ippInterpolation, border_type, border_value, &ok);
473
+ cv::Range range (0 , dst_height);
474
+ cv::parallel_for_ (range, invoker, dst_width * dst_height / (double )(1 << 16 ));
475
+
476
+ if (ok)
477
+ {
478
+ CV_IMPL_ADD (CV_IMPL_IPP | CV_IMPL_MT);
479
+ return CV_HAL_ERROR_OK;
480
+ }
481
+ }
482
+ }
483
+ return CV_HAL_ERROR_NOT_IMPLEMENTED;
484
+ }
0 commit comments