@@ -495,6 +495,40 @@ inline double cubic_3d(
495495 return value;
496496}
497497
498+ // Dispatch to the per-voxel sampler for the requested interpolation order. Shared by the affine and
499+ // map_coordinates kernels so the interpolation backend lives in exactly one place. `order` must be in
500+ // 0..5 (validated by the public entry points before the sampling loop).
501+ template <class T >
502+ inline double sample_2d (
503+ const T *data, std::ptrdiff_t in_h, std::ptrdiff_t in_w,
504+ double cy, double cx, const int order, double fill
505+ ) {
506+ switch (order) {
507+ case 0 : return nearest_2d (data, in_h, in_w, cy, cx, fill);
508+ case 1 : return linear_2d (data, in_h, in_w, cy, cx, fill);
509+ case 2 : return bspline_2d<2 >(data, in_h, in_w, cy, cx, fill);
510+ case 3 : return cubic_2d (data, in_h, in_w, cy, cx, fill);
511+ case 4 : return bspline_2d<4 >(data, in_h, in_w, cy, cx, fill);
512+ default : return bspline_2d<5 >(data, in_h, in_w, cy, cx, fill); // 5
513+ }
514+ }
515+
516+ template <class T >
517+ inline double sample_3d (
518+ const T *data,
519+ std::ptrdiff_t in_d, std::ptrdiff_t in_h, std::ptrdiff_t in_w,
520+ double cz, double cy, double cx, const int order, double fill
521+ ) {
522+ switch (order) {
523+ case 0 : return nearest_3d (data, in_d, in_h, in_w, cz, cy, cx, fill);
524+ case 1 : return linear_3d (data, in_d, in_h, in_w, cz, cy, cx, fill);
525+ case 2 : return bspline_3d<2 >(data, in_d, in_h, in_w, cz, cy, cx, fill);
526+ case 3 : return cubic_3d (data, in_d, in_h, in_w, cz, cy, cx, fill);
527+ case 4 : return bspline_3d<4 >(data, in_d, in_h, in_w, cz, cy, cx, fill);
528+ default : return bspline_3d<5 >(data, in_d, in_h, in_w, cz, cy, cx, fill); // 5
529+ }
530+ }
531+
498532} // namespace detail
499533
500534// ----- 2D entry point -------------------------------------------------------
@@ -554,27 +588,7 @@ void affine_transform_2d(
554588 double cy = row_y;
555589 double cx = row_x;
556590 for (std::ptrdiff_t j = 0 ; j < out_w; ++j) {
557- double value;
558- switch (order) {
559- case 0 :
560- value = detail::nearest_2d (in_data, in_h, in_w, cy, cx, fill);
561- break ;
562- case 1 :
563- value = detail::linear_2d (in_data, in_h, in_w, cy, cx, fill);
564- break ;
565- case 2 :
566- value = detail::bspline_2d<2 >(in_data, in_h, in_w, cy, cx, fill);
567- break ;
568- case 3 :
569- value = detail::cubic_2d (in_data, in_h, in_w, cy, cx, fill);
570- break ;
571- case 4 :
572- value = detail::bspline_2d<4 >(in_data, in_h, in_w, cy, cx, fill);
573- break ;
574- default : // 5
575- value = detail::bspline_2d<5 >(in_data, in_h, in_w, cy, cx, fill);
576- break ;
577- }
591+ const double value = detail::sample_2d (in_data, in_h, in_w, cy, cx, order, fill);
578592 *out_ptr++ = detail::to_output<T>(value);
579593 cy += m01;
580594 cx += m11;
@@ -655,33 +669,8 @@ void affine_transform_3d(
655669 double cy = row_y;
656670 double cx = row_x;
657671 for (std::ptrdiff_t j = 0 ; j < out_w; ++j) {
658- double value;
659- switch (order) {
660- case 0 :
661- value = detail::nearest_3d (in_data, in_d, in_h, in_w,
662- cz, cy, cx, fill);
663- break ;
664- case 1 :
665- value = detail::linear_3d (in_data, in_d, in_h, in_w,
666- cz, cy, cx, fill);
667- break ;
668- case 2 :
669- value = detail::bspline_3d<2 >(in_data, in_d, in_h, in_w,
670- cz, cy, cx, fill);
671- break ;
672- case 3 :
673- value = detail::cubic_3d (in_data, in_d, in_h, in_w,
674- cz, cy, cx, fill);
675- break ;
676- case 4 :
677- value = detail::bspline_3d<4 >(in_data, in_d, in_h, in_w,
678- cz, cy, cx, fill);
679- break ;
680- default : // 5
681- value = detail::bspline_3d<5 >(in_data, in_d, in_h, in_w,
682- cz, cy, cx, fill);
683- break ;
684- }
672+ const double value = detail::sample_3d (in_data, in_d, in_h, in_w,
673+ cz, cy, cx, order, fill);
685674 *out_ptr++ = detail::to_output<T>(value);
686675 cz += m02;
687676 cy += m12;
0 commit comments