diff --git a/hal/riscv-rvv/src/core/convert_scale.cpp b/hal/riscv-rvv/src/core/convert_scale.cpp index 8c5f83a677..bb0286354c 100644 --- a/hal/riscv-rvv/src/core/convert_scale.cpp +++ b/hal/riscv-rvv/src/core/convert_scale.cpp @@ -62,6 +62,79 @@ inline int convertScale_8U32F(const uchar* src, size_t src_step, uchar* dst, siz return CV_HAL_ERROR_OK; } +inline int convertScale_16U32F(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta) +{ + int vlmax = __riscv_vsetvlmax_e32m8(); + auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax); + float a = alpha; + + for (int i = 0; i < height; i++) + { + const ushort* src_row = reinterpret_cast(src + i * src_step); + float* dst_row = reinterpret_cast(dst + i * dst_step); + int vl; + for (int j = 0; j < width; j += vl) + { + vl = __riscv_vsetvl_e16m4(width - j); + auto vec_src = __riscv_vle16_v_u16m4(src_row + j, vl); + auto vec_src_f32 = __riscv_vfwcvt_f(vec_src, vl); + auto vec_fma = __riscv_vfmadd(vec_src_f32, a, vec_b, vl); + __riscv_vse32_v_f32m8(dst_row + j, vec_fma, vl); + } + } + + return CV_HAL_ERROR_OK; +} + +inline int convertScale_16S32F(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta) +{ + int vlmax = __riscv_vsetvlmax_e32m8(); + auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax); + float a = alpha; + + for (int i = 0; i < height; i++) + { + const short* src_row = reinterpret_cast(src + i * src_step); + float* dst_row = reinterpret_cast(dst + i * dst_step); + int vl; + for (int j = 0; j < width; j += vl) + { + vl = __riscv_vsetvl_e16m4(width - j); + auto vec_src = __riscv_vle16_v_i16m4(src_row + j, vl); + auto vec_src_f32 = __riscv_vfwcvt_f(vec_src, vl); + auto vec_fma = __riscv_vfmadd(vec_src_f32, a, vec_b, vl); + __riscv_vse32_v_f32m8(dst_row + j, vec_fma, vl); + } + } + + return CV_HAL_ERROR_OK; +} + +inline int convertScale_32F8U(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta) +{ + int vlmax = __riscv_vsetvlmax_e32m8(); + auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax); + float a = alpha; + + for (int i = 0; i < height; i++) + { + const float* src_row = reinterpret_cast(src + i * src_step); + uchar* dst_row = dst + i * dst_step; + int vl; + for (int j = 0; j < width; j += vl) + { + vl = __riscv_vsetvl_e32m8(width - j); + auto vec_src = __riscv_vle32_v_f32m8(src_row + j, vl); + auto vec_fma = __riscv_vfmadd(vec_src, a, vec_b, vl); + auto vec_dst_u16 = __riscv_vfncvt_xu(vec_fma, vl); + auto vec_dst = __riscv_vnclipu(vec_dst_u16, 0, __RISCV_VXRM_RNU, vl); + __riscv_vse8_v_u8m2(dst_row + j, vec_dst, vl); + } + } + + return CV_HAL_ERROR_OK; +} + inline int convertScale_32F32F(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta) { int vlmax = __riscv_vsetvlmax_e32m8(); @@ -102,9 +175,25 @@ int convertScale(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, return convertScale_8U32F(src, src_step, dst, dst_step, width, height, alpha, beta); } return CV_HAL_ERROR_NOT_IMPLEMENTED; + case CV_16U: + switch (ddepth) + { + case CV_32F: + return convertScale_16U32F(src, src_step, dst, dst_step, width, height, alpha, beta); + } + return CV_HAL_ERROR_NOT_IMPLEMENTED; + case CV_16S: + switch (ddepth) + { + case CV_32F: + return convertScale_16S32F(src, src_step, dst, dst_step, width, height, alpha, beta); + } + return CV_HAL_ERROR_NOT_IMPLEMENTED; case CV_32F: switch (ddepth) { + case CV_8U: + return convertScale_32F8U(src, src_step, dst, dst_step, width, height, alpha, beta); case CV_32F: return convertScale_32F32F(src, src_step, dst, dst_step, width, height, alpha, beta); }