mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge branch 4.x
This commit is contained in:
+3
-3
@@ -247,15 +247,15 @@ int fastcv_hal_cvtBGRtoYUVApprox(
|
||||
/// @param width Source image width
|
||||
/// @param height Source image height
|
||||
/// @param cn Number of channels
|
||||
/// @param lowThreshold low hresholds value
|
||||
/// @param lowThreshold low thresholds value
|
||||
/// @param highThreshold high thresholds value
|
||||
/// @param ksize Kernel size for Sobel operator.
|
||||
/// @param L2gradient Flag, indicating use of L2 or L1 norma.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int fastcv_hal_canny(
|
||||
const uchar* src_data,
|
||||
const uchar* src_data,
|
||||
size_t src_step,
|
||||
uchar* dst_data,
|
||||
uchar* dst_data,
|
||||
size_t dst_step,
|
||||
int width,
|
||||
int height,
|
||||
|
||||
+35
-75
@@ -75,13 +75,13 @@ class FcvSobelLoop_Invoker : public cv::ParallelLoopBody
|
||||
// Need additional lines to be border.
|
||||
if(range.start > 0)
|
||||
{
|
||||
topLines += halfKernelSize;
|
||||
paddedHeight += halfKernelSize;
|
||||
topLines += MIN(range.start, halfKernelSize);
|
||||
paddedHeight += MIN(range.start, halfKernelSize);
|
||||
}
|
||||
|
||||
if(range.end < height)
|
||||
{
|
||||
paddedHeight += halfKernelSize;
|
||||
paddedHeight += MIN(height-range.end, halfKernelSize);
|
||||
}
|
||||
|
||||
cv::Mat srcPadded = src(cv::Rect(0, range.start-topLines, width, paddedHeight));
|
||||
@@ -305,8 +305,9 @@ int fastcv_hal_sobel(
|
||||
else
|
||||
{
|
||||
int nThreads = cv::getNumThreads();
|
||||
int nStripes = nThreads > 1 ? 3*nThreads : 1;
|
||||
|
||||
// In each stripe, the height should be equal or larger than ksize.
|
||||
// Use 3*nThreads stripes to avoid too many threads.
|
||||
int nStripes = nThreads > 1 ? MIN(height / (int)ksize, 3 * nThreads) : 1;
|
||||
cv::parallel_for_(cv::Range(0, height), FcvSobelLoop_Invoker(src, dst, dx, dy, ksize, fcvBorder, 0), nStripes);
|
||||
}
|
||||
|
||||
@@ -466,47 +467,30 @@ class FcvGaussianBlurLoop_Invoker : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
|
||||
FcvGaussianBlurLoop_Invoker(const cv::Mat& _src, cv::Mat& _dst, int _ksize, fcvBorderType _fcvBorder, int _fcvBorderValue) :
|
||||
cv::ParallelLoopBody(), src(_src),dst(_dst), ksize(_ksize), fcvBorder(_fcvBorder), fcvBorderValue(_fcvBorderValue)
|
||||
FcvGaussianBlurLoop_Invoker(const cv::Mat& _src, cv::Mat& _dst, int _ksize, int _borderType, int _fcvBorderValue) :
|
||||
cv::ParallelLoopBody(), src(_src),dst(_dst), ksize(_ksize), borderType(_borderType), fcvBorderValue(_fcvBorderValue)
|
||||
{
|
||||
width = src.cols;
|
||||
height = src.rows;
|
||||
halfKernelSize = ksize / 2;
|
||||
halfKSize = ksize / 2;
|
||||
fcvFuncType = FCV_MAKETYPE(ksize, src.depth());
|
||||
}
|
||||
|
||||
virtual void operator()(const cv::Range& range) const CV_OVERRIDE
|
||||
{
|
||||
int topLines = 0;
|
||||
int rangeHeight = range.end-range.start;
|
||||
int paddedHeight = rangeHeight;
|
||||
int rangeHeight = range.end - range.start;
|
||||
int paddedHeight = rangeHeight + halfKSize * 2;
|
||||
int paddedWidth = width;
|
||||
|
||||
// Need additional lines to be border.
|
||||
if(range.start != 0)
|
||||
{
|
||||
topLines += halfKernelSize;
|
||||
paddedHeight += halfKernelSize;
|
||||
}
|
||||
|
||||
if(range.end != height)
|
||||
{
|
||||
paddedHeight += halfKernelSize;
|
||||
}
|
||||
|
||||
const cv::Mat srcPadded = src(cv::Rect(0, range.start - topLines, width, paddedHeight));
|
||||
cv::Mat dstPadded = cv::Mat(paddedHeight, width, CV_8U);
|
||||
cv::Mat srcPadded = src(cv::Rect(0, range.start, paddedWidth, paddedHeight));
|
||||
cv::Mat dstPadded = dst(cv::Rect(0, range.start, paddedWidth, paddedHeight));
|
||||
|
||||
if (fcvFuncType == FCV_MAKETYPE(3,CV_8U))
|
||||
fcvFilterGaussian3x3u8_v4(srcPadded.data, width, paddedHeight, srcPadded.step, dstPadded.data, dstPadded.step,
|
||||
fcvBorder, 0);
|
||||
fcvFilterGaussian3x3u8_v4(srcPadded.data, paddedWidth, paddedHeight, srcPadded.step, dstPadded.data, dstPadded.step,
|
||||
fcvBorderType::FASTCV_BORDER_UNDEFINED, fcvBorderValue);
|
||||
else if (fcvFuncType == FCV_MAKETYPE(5,CV_8U))
|
||||
fcvFilterGaussian5x5u8_v3(srcPadded.data, width, paddedHeight, srcPadded.step, dstPadded.data, dstPadded.step,
|
||||
fcvBorder, 0);
|
||||
|
||||
// Only copy center part back to output image and ignore the padded lines
|
||||
cv::Mat temp1 = dstPadded(cv::Rect(0, topLines, width, rangeHeight));
|
||||
cv::Mat temp2 = dst(cv::Rect(0, range.start, width, rangeHeight));
|
||||
temp1.copyTo(temp2);
|
||||
fcvFilterGaussian5x5u8_v3(srcPadded.data, paddedWidth, paddedHeight, srcPadded.step, dstPadded.data, dstPadded.step,
|
||||
fcvBorderType::FASTCV_BORDER_UNDEFINED, fcvBorderValue);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -515,9 +499,9 @@ class FcvGaussianBlurLoop_Invoker : public cv::ParallelLoopBody
|
||||
int width;
|
||||
int height;
|
||||
const int ksize;
|
||||
int halfKernelSize;
|
||||
int halfKSize;
|
||||
int fcvFuncType;
|
||||
fcvBorderType fcvBorder;
|
||||
int borderType;
|
||||
int fcvBorderValue;
|
||||
|
||||
FcvGaussianBlurLoop_Invoker(const FcvGaussianBlurLoop_Invoker &); // = delete;
|
||||
@@ -544,9 +528,9 @@ int fastcv_hal_gaussianBlurBinomial(
|
||||
if (src_data == dst_data)
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("Inplace is not supported");
|
||||
|
||||
// The input image width and height should greater than kernel size
|
||||
if (((size_t)height <= ksize) || ((size_t)width <= ksize))
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("Input image size should be larger than kernel size");
|
||||
// The pixels of input image should larger than 320*240
|
||||
if((width*height) < (320*240))
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("Input image size should be larger than 320*240");
|
||||
|
||||
// The input channel should be 1
|
||||
if (cn != 1)
|
||||
@@ -559,35 +543,7 @@ int fastcv_hal_gaussianBlurBinomial(
|
||||
INITIALIZATION_CHECK;
|
||||
|
||||
fcvStatus status = FASTCV_SUCCESS;
|
||||
fcvBorderType fcvBorder = fcvBorderType::FASTCV_BORDER_UNDEFINED;
|
||||
int fcvFuncType = FCV_MAKETYPE(ksize,depth);
|
||||
|
||||
switch (border_type)
|
||||
{
|
||||
case cv::BorderTypes::BORDER_REPLICATE:
|
||||
{
|
||||
fcvBorder = fcvBorderType::FASTCV_BORDER_REPLICATE;
|
||||
break;
|
||||
}
|
||||
// For constant border, there are no border value, OpenCV default value is 0
|
||||
case cv::BorderTypes::BORDER_CONSTANT:
|
||||
{
|
||||
fcvBorder = fcvBorderType::FASTCV_BORDER_CONSTANT;
|
||||
break;
|
||||
}
|
||||
case cv::BorderTypes::BORDER_REFLECT:
|
||||
{
|
||||
fcvBorder = fcvBorderType::FASTCV_BORDER_REFLECT;
|
||||
break;
|
||||
}
|
||||
case cv::BorderTypes::BORDER_REFLECT_101:
|
||||
{
|
||||
fcvBorder = fcvBorderType::FASTCV_BORDER_REFLECT_V2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("Border type:%s is not supported", borderToString(border_type)));
|
||||
}
|
||||
int fcvFuncType = FCV_MAKETYPE(ksize, depth);
|
||||
|
||||
int nThreads = cv::getNumThreads();
|
||||
int nStripes = (nThreads > 1) ? ((height > 60) ? 3 * nThreads : 1) : 1;
|
||||
@@ -597,9 +553,13 @@ int fastcv_hal_gaussianBlurBinomial(
|
||||
case FCV_MAKETYPE(3,CV_8U):
|
||||
case FCV_MAKETYPE(5,CV_8U):
|
||||
{
|
||||
cv::Mat src = cv::Mat(height, width, CV_8UC1, (void*)src_data, src_step);
|
||||
cv::Mat dst = cv::Mat(height, width, CV_8UC1, (void*)dst_data, dst_step);
|
||||
cv::parallel_for_(cv::Range(0, height), FcvGaussianBlurLoop_Invoker(src, dst, ksize, fcvBorder, 0), nStripes);
|
||||
cv::Mat src = cv::Mat(height, width, CV_8UC1, (void *)src_data, src_step);
|
||||
cv::Mat dst = cv::Mat(height, width, CV_8UC1, (void *)dst_data, dst_step);
|
||||
cv::Mat src_tmp = cv::Mat(height + ksize - 1, width + ksize - 1, CV_8UC1);
|
||||
cv::Mat dst_tmp = cv::Mat(height + ksize - 1, width + ksize - 1, CV_8UC1);
|
||||
cv::copyMakeBorder(src, src_tmp, ksize / 2, ksize / 2, ksize / 2, ksize / 2, border_type);
|
||||
cv::parallel_for_(cv::Range(0, height), FcvGaussianBlurLoop_Invoker(src_tmp, dst_tmp, ksize, border_type, 0), nStripes);
|
||||
dst_tmp(cv::Rect(ksize / 2, ksize / 2, width, height)).copyTo(dst);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1017,10 +977,10 @@ int fastcv_hal_canny(
|
||||
|
||||
if (lowThreshold > highThreshold)
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("lowThreshold is greater then highThreshold");
|
||||
|
||||
const double epsilon = 1e-9;
|
||||
|
||||
if (std::abs(lowThreshold - std::round(lowThreshold)) > epsilon || std::abs(highThreshold - std::round(highThreshold)) > epsilon)
|
||||
|
||||
const double epsilon = 1e-9;
|
||||
|
||||
if (std::abs(lowThreshold - std::round(lowThreshold)) > epsilon || std::abs(highThreshold - std::round(highThreshold)) > epsilon)
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("threshold with decimal values not supported");
|
||||
|
||||
INITIALIZATION_CHECK;
|
||||
|
||||
Vendored
+12
@@ -22,6 +22,7 @@
|
||||
#if defined(__riscv_v) && __riscv_v == 1000000
|
||||
#include "hal_rvv_1p0/merge.hpp" // core
|
||||
#include "hal_rvv_1p0/mean.hpp" // core
|
||||
#include "hal_rvv_1p0/dxt.hpp" // core
|
||||
#include "hal_rvv_1p0/norm.hpp" // core
|
||||
#include "hal_rvv_1p0/norm_diff.hpp" // core
|
||||
#include "hal_rvv_1p0/norm_hamming.hpp" // core
|
||||
@@ -30,6 +31,17 @@
|
||||
#include "hal_rvv_1p0/atan.hpp" // core
|
||||
#include "hal_rvv_1p0/split.hpp" // core
|
||||
#include "hal_rvv_1p0/flip.hpp" // core
|
||||
#include "hal_rvv_1p0/lut.hpp" // core
|
||||
#include "hal_rvv_1p0/exp.hpp" // core
|
||||
#include "hal_rvv_1p0/log.hpp" // core
|
||||
#include "hal_rvv_1p0/lu.hpp" // core
|
||||
#include "hal_rvv_1p0/cholesky.hpp" // core
|
||||
#include "hal_rvv_1p0/qr.hpp" // core
|
||||
#include "hal_rvv_1p0/svd.hpp" // core
|
||||
|
||||
#include "hal_rvv_1p0/filter.hpp" // imgproc
|
||||
#include "hal_rvv_1p0/pyramids.hpp" // imgproc
|
||||
#include "hal_rvv_1p0/color.hpp" // imgproc
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_CHOLESKY_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_CHOLESKY_HPP_INCLUDED
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <riscv_vector.h>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv { namespace cholesky {
|
||||
|
||||
#undef cv_hal_Cholesky32f
|
||||
#define cv_hal_Cholesky32f cv::cv_hal_rvv::cholesky::Cholesky<cv::cv_hal_rvv::RVV_F32M4>
|
||||
#undef cv_hal_Cholesky64f
|
||||
#define cv_hal_Cholesky64f cv::cv_hal_rvv::cholesky::Cholesky<cv::cv_hal_rvv::RVV_F64M4>
|
||||
|
||||
// the algorithm is copied from core/src/matrix_decomp.cpp,
|
||||
// in the function template static int cv::CholImpl
|
||||
template <typename RVV_T, typename T = typename RVV_T::ElemType>
|
||||
inline int Cholesky(T* src1, size_t src1_step, int m, T* src2, size_t src2_step, int n, bool* info)
|
||||
{
|
||||
int i, j, k;
|
||||
double s;
|
||||
src1_step /= sizeof(src1[0]);
|
||||
src2_step /= sizeof(src2[0]);
|
||||
|
||||
int vlmax = RVV_T::setvlmax(), vl;
|
||||
for( i = 0; i < m; i++ )
|
||||
{
|
||||
for( j = 0; j < i; j++ )
|
||||
{
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < j; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(j - k);
|
||||
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(src1 + j * src1_step + k, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
s = src1[i*src1_step + j] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
|
||||
src1[i*src1_step + j] = (T)(s*src1[j*src1_step + j]);
|
||||
}
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < j; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(j - k);
|
||||
auto vec_src = RVV_T::vload(src1 + i * src1_step + k, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src, vec_src, vl);
|
||||
}
|
||||
s = src1[i*src1_step + i] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
|
||||
if( s < std::numeric_limits<T>::epsilon() )
|
||||
{
|
||||
*info = false;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
src1[i*src1_step + i] = (T)(1./std::sqrt(s));
|
||||
}
|
||||
|
||||
if (!src2)
|
||||
{
|
||||
for( i = 0; i < m; i += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - i);
|
||||
auto vec_src = RVV_T::vload_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vl);
|
||||
vec_src = __riscv_vfrdiv(vec_src, 1, vl);
|
||||
RVV_T::vstore_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vec_src, vl);
|
||||
}
|
||||
*info = true;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
for( i = 0; i < m; i++ )
|
||||
{
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < i; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(i - k);
|
||||
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + k, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src2 + k * src2_step + j, sizeof(T) * src2_step, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
s = src2[i*src2_step + j] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
|
||||
src2[i*src2_step + j] = (T)(s*src1[i*src1_step + i]);
|
||||
}
|
||||
}
|
||||
|
||||
for( i = m-1; i >= 0; i-- )
|
||||
{
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = i + 1; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload_stride(src1 + k * src1_step + i, sizeof(T) * src1_step, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src2 + k * src2_step + j, sizeof(T) * src2_step, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
s = src2[i*src2_step + j] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
|
||||
src2[i*src2_step + j] = (T)(s*src1[i*src1_step + i]);
|
||||
}
|
||||
}
|
||||
for( i = 0; i < m; i += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - i);
|
||||
auto vec_src = RVV_T::vload_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vl);
|
||||
vec_src = __riscv_vfrdiv(vec_src, 1, vl);
|
||||
RVV_T::vstore_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vec_src, vl);
|
||||
}
|
||||
|
||||
*info = true;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+3010
File diff suppressed because it is too large
Load Diff
Vendored
+565
@@ -0,0 +1,565 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_DXT_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_DXT_HPP_INCLUDED
|
||||
|
||||
#include <riscv_vector.h>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
#include "opencv2/core/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv { namespace dxt {
|
||||
|
||||
#undef cv_hal_dft
|
||||
#define cv_hal_dft cv::cv_hal_rvv::dxt::dft
|
||||
|
||||
template<typename T> struct rvv;
|
||||
|
||||
template<> struct rvv<float> : RVV_F32MF2
|
||||
{
|
||||
using T = RVV_F32MF2::VecType;
|
||||
using TabType = RVV_U32M8;
|
||||
using TabTypeF = RVV_SameLen<float, TabType>;
|
||||
static inline void vlseg(const float* a, T& b, T& c, size_t d) { auto x = __riscv_vlseg2e32_v_f32mf2x2(a, d); b = __riscv_vget_v_f32mf2x2_f32mf2(x, 0), c = __riscv_vget_v_f32mf2x2_f32mf2(x, 1); }
|
||||
static inline void vlsseg(const float* a, ptrdiff_t b, T& c, T& d, size_t e) { auto x = __riscv_vlsseg2e32_v_f32mf2x2(a, b, e); c = __riscv_vget_v_f32mf2x2_f32mf2(x, 0), d = __riscv_vget_v_f32mf2x2_f32mf2(x, 1); }
|
||||
static inline void vsseg(float* a, T b, T c, size_t d) { __riscv_vsseg2e32(a, __riscv_vset_v_f32mf2_f32mf2x2(__riscv_vset_v_f32mf2_f32mf2x2(vfloat32mf2x2_t(), 0, b), 1, c), d); }
|
||||
};
|
||||
|
||||
template<> struct rvv<double> : RVV_F64M1
|
||||
{
|
||||
using T = RVV_F64M1::VecType;
|
||||
using TabType = RVV_U32M4;
|
||||
using TabTypeF = RVV_SameLen<double, TabType>;
|
||||
static inline void vlseg(const double* a, T& b, T& c, size_t d) { auto x = __riscv_vlseg2e64_v_f64m1x2(a, d); b = __riscv_vget_v_f64m1x2_f64m1(x, 0), c = __riscv_vget_v_f64m1x2_f64m1(x, 1); }
|
||||
static inline void vlsseg(const double* a, ptrdiff_t b, T& c, T& d, size_t e) { auto x = __riscv_vlsseg2e64_v_f64m1x2(a, b, e); c = __riscv_vget_v_f64m1x2_f64m1(x, 0), d = __riscv_vget_v_f64m1x2_f64m1(x, 1); }
|
||||
static inline void vsseg(double* a, T b, T c, size_t d) { __riscv_vsseg2e64(a, __riscv_vset_v_f64m1_f64m1x2(__riscv_vset_v_f64m1_f64m1x2(vfloat64m1x2_t(), 0, b), 1, c), d); }
|
||||
};
|
||||
|
||||
// the algorithm is copied from core/src/dxt.cpp,
|
||||
// in the function template static void cv::DFT and cv::DFT_R2, cv::DFT_R3, cv::DFT_R5
|
||||
template <typename T>
|
||||
inline int dft(const Complex<T>* src, Complex<T>* dst, int nf, int *factors, T scale, int* itab,
|
||||
const Complex<T>* wave, int tab_size, int len, bool isInverse, bool noPermute)
|
||||
{
|
||||
int n = len;
|
||||
int f_idx, nx;
|
||||
int dw0 = tab_size, dw;
|
||||
int i, j, k;
|
||||
Complex<T> t;
|
||||
using VT = typename rvv<T>::VecType;
|
||||
using TabType = typename rvv<T>::TabType;
|
||||
using TabTypeF = typename rvv<T>::TabTypeF;
|
||||
|
||||
int tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n;
|
||||
int vl;
|
||||
|
||||
// 0. shuffle data
|
||||
if( dst != src )
|
||||
{
|
||||
if( !isInverse )
|
||||
{
|
||||
for( i = 0; i < n; i += vl )
|
||||
{
|
||||
vl = TabType::setvl(n - i);
|
||||
auto vec_itab = TabType::vload_stride(reinterpret_cast<const uint*>(itab + i * tab_step), sizeof(int) * tab_step, vl);
|
||||
vec_itab = __riscv_vmul(vec_itab, sizeof(T) * 2, vl);
|
||||
auto vec_src_re = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
|
||||
vec_itab = __riscv_vadd(vec_itab, sizeof(T), vl);
|
||||
auto vec_src_im = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i), sizeof(T) * 2, vec_src_re, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < n; i += vl )
|
||||
{
|
||||
vl = TabType::setvl(n - i);
|
||||
auto vec_itab = TabType::vload_stride(reinterpret_cast<const uint*>(itab + i * tab_step), sizeof(int) * tab_step, vl);
|
||||
vec_itab = __riscv_vmul(vec_itab, sizeof(T) * 2, vl);
|
||||
auto vec_src_re = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
|
||||
vec_itab = __riscv_vadd(vec_itab, sizeof(T), vl);
|
||||
auto vec_src_im = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
|
||||
vec_src_im = __riscv_vfneg(vec_src_im, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i), sizeof(T) * 2, vec_src_re, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// copied from core/src/dxt.cpp, it is slow to swap elements by intrinsics
|
||||
if( !noPermute )
|
||||
{
|
||||
if( nf == 1 )
|
||||
{
|
||||
if( (n & 3) == 0 )
|
||||
{
|
||||
int n2 = n/2;
|
||||
Complex<T>* dsth = dst + n2;
|
||||
|
||||
for( i = 0; i < n2; i += 2, itab += tab_step*2 )
|
||||
{
|
||||
j = itab[0];
|
||||
|
||||
t = dst[i+1], dst[i+1] = dsth[j], dsth[j] = t;
|
||||
if( j > i )
|
||||
{
|
||||
t = dst[i], dst[i] = dst[j], dst[j] = t;
|
||||
t = dsth[i+1], dsth[i+1] = dsth[j+1], dsth[j+1] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
// else do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < n; i++, itab += tab_step )
|
||||
{
|
||||
j = itab[0];
|
||||
if( j > i )
|
||||
t = dst[i], dst[i] = dst[j], dst[j] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( isInverse )
|
||||
{
|
||||
for( i = 0; i < n; i += vl )
|
||||
{
|
||||
vl = TabType::setvl(n - i);
|
||||
auto vec_src_im = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i) + 1, sizeof(T) * 2, vl);
|
||||
vec_src_im = __riscv_vfneg(vec_src_im, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
n = 1;
|
||||
// 1. power-2 transforms
|
||||
if( (factors[0] & 1) == 0 )
|
||||
{
|
||||
// radix-4 transform
|
||||
for( ; n*4 <= factors[0]; )
|
||||
{
|
||||
nx = n;
|
||||
n *= 4;
|
||||
dw0 /= 4;
|
||||
|
||||
for( i = 0; i < len; i += n )
|
||||
{
|
||||
Complex<T> *v0, *v1;
|
||||
T r0, i0, r1, i1, r2, i2, r3, i3, r4, i4;
|
||||
|
||||
v0 = dst + i;
|
||||
v1 = v0 + nx*2;
|
||||
|
||||
r0 = v1[0].re; i0 = v1[0].im;
|
||||
r4 = v1[nx].re; i4 = v1[nx].im;
|
||||
|
||||
r1 = r0 + r4; i1 = i0 + i4;
|
||||
r3 = i0 - i4; i3 = r4 - r0;
|
||||
|
||||
r2 = v0[0].re; i2 = v0[0].im;
|
||||
r4 = v0[nx].re; i4 = v0[nx].im;
|
||||
|
||||
r0 = r2 + r4; i0 = i2 + i4;
|
||||
r2 -= r4; i2 -= i4;
|
||||
|
||||
v0[0].re = r0 + r1; v0[0].im = i0 + i1;
|
||||
v1[0].re = r0 - r1; v1[0].im = i0 - i1;
|
||||
v0[nx].re = r2 + r3; v0[nx].im = i2 + i3;
|
||||
v1[nx].re = r2 - r3; v1[nx].im = i2 - i3;
|
||||
|
||||
for( j = 1; j < nx; j += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(nx - j);
|
||||
v0 = dst + i + j;
|
||||
v1 = v0 + nx*2;
|
||||
|
||||
VT vec_re, vec_im, vec_w_re, vec_w_im;
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v1), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r0 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
auto vec_i0 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v1 + nx), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 3), sizeof(T) * dw0 * 6, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r3 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
auto vec_i3 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
|
||||
auto vec_r1 = __riscv_vfadd(vec_i0, vec_i3, vl);
|
||||
auto vec_i1 = __riscv_vfadd(vec_r0, vec_r3, vl);
|
||||
vec_r3 = __riscv_vfsub(vec_r0, vec_r3, vl);
|
||||
vec_i3 = __riscv_vfsub(vec_i3, vec_i0, vl);
|
||||
VT vec_r4, vec_i4;
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v0), vec_r4, vec_i4, vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v0 + nx), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 2), sizeof(T) * dw0 * 4, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
vec_r0 = __riscv_vfadd(vec_r4, vec_r2, vl);
|
||||
vec_i0 = __riscv_vfadd(vec_i4, vec_i2, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v0), __riscv_vfadd(vec_r0, vec_r1, vl), __riscv_vfadd(vec_i0, vec_i1, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v1), __riscv_vfsub(vec_r0, vec_r1, vl), __riscv_vfsub(vec_i0, vec_i1, vl), vl);
|
||||
|
||||
vec_r2 = __riscv_vfsub(vec_r4, vec_r2, vl);
|
||||
vec_i2 = __riscv_vfsub(vec_i4, vec_i2, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v0 + nx), __riscv_vfadd(vec_r2, vec_r3, vl), __riscv_vfadd(vec_i2, vec_i3, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v1 + nx), __riscv_vfsub(vec_r2, vec_r3, vl), __riscv_vfsub(vec_i2, vec_i3, vl), vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( ; n < factors[0]; )
|
||||
{
|
||||
// do the remaining radix-2 transform
|
||||
nx = n;
|
||||
n *= 2;
|
||||
dw0 /= 2;
|
||||
|
||||
for( i = 0; i < len; i += n )
|
||||
{
|
||||
Complex<T>* v = dst + i;
|
||||
T r0 = v[0].re + v[nx].re;
|
||||
T i0 = v[0].im + v[nx].im;
|
||||
T r1 = v[0].re - v[nx].re;
|
||||
T i1 = v[0].im - v[nx].im;
|
||||
v[0].re = r0; v[0].im = i0;
|
||||
v[nx].re = r1; v[nx].im = i1;
|
||||
|
||||
for( j = 1; j < nx; j += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(nx - j);
|
||||
v = dst + i + j;
|
||||
|
||||
VT vec_re, vec_im, vec_w_re, vec_w_im;
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v + nx), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
|
||||
|
||||
auto vec_r1 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i1 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
VT vec_r0, vec_i0;
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v), vec_r0, vec_i0, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v), __riscv_vfadd(vec_r0, vec_r1, vl), __riscv_vfadd(vec_i0, vec_i1, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v + nx), __riscv_vfsub(vec_r0, vec_r1, vl), __riscv_vfsub(vec_i0, vec_i1, vl), vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. all the other transforms
|
||||
for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ )
|
||||
{
|
||||
int factor = factors[f_idx];
|
||||
nx = n;
|
||||
n *= factor;
|
||||
dw0 /= factor;
|
||||
|
||||
if( factor == 3 )
|
||||
{
|
||||
const T sin_120 = 0.86602540378443864676372317075294;
|
||||
for( i = 0; i < len; i += n )
|
||||
{
|
||||
Complex<T>* v = dst + i;
|
||||
T r1 = v[nx].re + v[nx*2].re;
|
||||
T i1 = v[nx].im + v[nx*2].im;
|
||||
T r0 = v[0].re;
|
||||
T i0 = v[0].im;
|
||||
T r2 = sin_120*(v[nx].im - v[nx*2].im);
|
||||
T i2 = sin_120*(v[nx*2].re - v[nx].re);
|
||||
v[0].re = r0 + r1; v[0].im = i0 + i1;
|
||||
r0 -= (T)0.5*r1; i0 -= (T)0.5*i1;
|
||||
v[nx].re = r0 + r2; v[nx].im = i0 + i2;
|
||||
v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
|
||||
|
||||
for( j = 1; j < nx; j += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(nx - j);
|
||||
v = dst + i + j;
|
||||
|
||||
VT vec_re, vec_im, vec_w_re, vec_w_im;
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v + nx), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r0 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i0 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v + nx * 2), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 2), sizeof(T) * dw0 * 4, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
auto vec_i2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
|
||||
auto vec_r1 = __riscv_vfadd(vec_r0, vec_i2, vl);
|
||||
auto vec_i1 = __riscv_vfadd(vec_i0, vec_r2, vl);
|
||||
|
||||
vec_r2 = __riscv_vfmul(__riscv_vfsub(vec_i0, vec_r2, vl), sin_120, vl);
|
||||
vec_i2 = __riscv_vfmul(__riscv_vfsub(vec_i2, vec_r0, vl), sin_120, vl);
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v), vec_r0, vec_i0, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v), __riscv_vfadd(vec_r0, vec_r1, vl), __riscv_vfadd(vec_i0, vec_i1, vl), vl);
|
||||
vec_r0 = __riscv_vfsub(vec_r0, __riscv_vfmul(vec_r1, 0.5, vl), vl);
|
||||
vec_i0 = __riscv_vfsub(vec_i0, __riscv_vfmul(vec_i1, 0.5, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v + nx), __riscv_vfadd(vec_r0, vec_r2, vl), __riscv_vfadd(vec_i0, vec_i2, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v + nx * 2), __riscv_vfsub(vec_r0, vec_r2, vl), __riscv_vfsub(vec_i0, vec_i2, vl), vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( factor == 5 )
|
||||
{
|
||||
const T fft5_2 = 0.559016994374947424102293417182819;
|
||||
const T fft5_3 = -0.951056516295153572116439333379382;
|
||||
const T fft5_4 = -1.538841768587626701285145288018455;
|
||||
const T fft5_5 = 0.363271264002680442947733378740309;
|
||||
for( i = 0; i < len; i += n )
|
||||
{
|
||||
for( j = 0; j < nx; j += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(nx - j);
|
||||
Complex<T>* v0 = dst + i + j;
|
||||
Complex<T>* v1 = v0 + nx*2;
|
||||
Complex<T>* v2 = v1 + nx*2;
|
||||
|
||||
VT vec_re, vec_im, vec_w_re, vec_w_im;
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v0 + nx), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r3 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i3 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v2), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 4), sizeof(T) * dw0 * 8, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
auto vec_r1 = __riscv_vfadd(vec_r3, vec_r2, vl);
|
||||
auto vec_i1 = __riscv_vfadd(vec_i3, vec_i2, vl);
|
||||
vec_r3 = __riscv_vfsub(vec_r3, vec_r2, vl);
|
||||
vec_i3 = __riscv_vfsub(vec_i3, vec_i2, vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v1 + nx), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 3), sizeof(T) * dw0 * 6, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r4 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i4 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v1), vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 2), sizeof(T) * dw0 * 4, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r0 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i0 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
vec_r2 = __riscv_vfadd(vec_r4, vec_r0, vl);
|
||||
vec_i2 = __riscv_vfadd(vec_i4, vec_i0, vl);
|
||||
vec_r4 = __riscv_vfsub(vec_r4, vec_r0, vl);
|
||||
vec_i4 = __riscv_vfsub(vec_i4, vec_i0, vl);
|
||||
|
||||
rvv<T>::vlseg(reinterpret_cast<const T*>(v0), vec_r0, vec_i0, vl);
|
||||
auto vec_r5 = __riscv_vfadd(vec_r1, vec_r2, vl);
|
||||
auto vec_i5 = __riscv_vfadd(vec_i1, vec_i2, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v0), __riscv_vfadd(vec_r0, vec_r5, vl), __riscv_vfadd(vec_i0, vec_i5, vl), vl);
|
||||
|
||||
vec_r0 = __riscv_vfsub(vec_r0, __riscv_vfmul(vec_r5, 0.25, vl), vl);
|
||||
vec_i0 = __riscv_vfsub(vec_i0, __riscv_vfmul(vec_i5, 0.25, vl), vl);
|
||||
vec_r1 = __riscv_vfmul(__riscv_vfsub(vec_r1, vec_r2, vl), fft5_2, vl);
|
||||
vec_i1 = __riscv_vfmul(__riscv_vfsub(vec_i1, vec_i2, vl), fft5_2, vl);
|
||||
vec_r2 = __riscv_vfmul(__riscv_vfadd(vec_i3, vec_i4, vl), -fft5_3, vl);
|
||||
vec_i2 = __riscv_vfmul(__riscv_vfadd(vec_r3, vec_r4, vl), fft5_3, vl);
|
||||
|
||||
vec_i3 = __riscv_vfmul(vec_i3, -fft5_5, vl);
|
||||
vec_r3 = __riscv_vfmul(vec_r3, fft5_5, vl);
|
||||
vec_i4 = __riscv_vfmul(vec_i4, -fft5_4, vl);
|
||||
vec_r4 = __riscv_vfmul(vec_r4, fft5_4, vl);
|
||||
|
||||
vec_r5 = __riscv_vfadd(vec_r2, vec_i3, vl);
|
||||
vec_i5 = __riscv_vfadd(vec_i2, vec_r3, vl);
|
||||
vec_r2 = __riscv_vfsub(vec_r2, vec_i4, vl);
|
||||
vec_i2 = __riscv_vfsub(vec_i2, vec_r4, vl);
|
||||
|
||||
vec_r3 = __riscv_vfadd(vec_r0, vec_r1, vl);
|
||||
vec_i3 = __riscv_vfadd(vec_i0, vec_i1, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v0 + nx), __riscv_vfadd(vec_r3, vec_r2, vl), __riscv_vfadd(vec_i3, vec_i2, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v2), __riscv_vfsub(vec_r3, vec_r2, vl), __riscv_vfsub(vec_i3, vec_i2, vl), vl);
|
||||
|
||||
vec_r0 = __riscv_vfsub(vec_r0, vec_r1, vl);
|
||||
vec_i0 = __riscv_vfsub(vec_i0, vec_i1, vl);
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v1), __riscv_vfadd(vec_r0, vec_r5, vl), __riscv_vfadd(vec_i0, vec_i5, vl), vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(v1 + nx), __riscv_vfsub(vec_r0, vec_r5, vl), __riscv_vfsub(vec_i0, vec_i5, vl), vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// radix-"factor" - an odd number
|
||||
int p, q, factor2 = (factor - 1)/2;
|
||||
int dd, dw_f = tab_size/factor;
|
||||
std::vector<Complex<T> > buf(factor2 * 2);
|
||||
Complex<T>* a = buf.data();
|
||||
Complex<T>* b = a + factor2;
|
||||
|
||||
for( i = 0; i < len; i += n )
|
||||
{
|
||||
for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
|
||||
{
|
||||
Complex<T>* v = dst + i + j;
|
||||
Complex<T> v_0 = v[0];
|
||||
Complex<T> vn_0 = v_0;
|
||||
|
||||
if( j == 0 )
|
||||
{
|
||||
for( p = 1; p <= factor2; p += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(factor2 + 1 - p);
|
||||
|
||||
VT vec_a_re, vec_a_im, vec_b_re, vec_b_im;
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + nx * p), sizeof(T) * nx * 2, vec_a_re, vec_a_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + n - nx * p), (ptrdiff_t)sizeof(T) * nx * -2, vec_b_re, vec_b_im, vl);
|
||||
auto vec_r0 = __riscv_vfadd(vec_a_re, vec_b_re, vl);
|
||||
auto vec_r1 = __riscv_vfsub(vec_a_re, vec_b_re, vl);
|
||||
auto vec_i0 = __riscv_vfsub(vec_a_im, vec_b_im, vl);
|
||||
auto vec_i1 = __riscv_vfadd(vec_a_im, vec_b_im, vl);
|
||||
|
||||
vn_0.re += __riscv_vfmv_f(__riscv_vfredosum(vec_r0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
vn_0.im += __riscv_vfmv_f(__riscv_vfredosum(vec_i1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(a + p - 1), vec_r0, vec_i0, vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(b + p - 1), vec_r1, vec_i1, vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const Complex<T>* wave_ = wave + dw*factor;
|
||||
|
||||
for( p = 1; p <= factor2; p += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(factor2 + 1 - p);
|
||||
|
||||
VT vec_re, vec_im, vec_w_re, vec_w_im;
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + nx * p), sizeof(T) * nx * 2, vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + p * dw), sizeof(T) * dw * 2, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + n - nx * p), (ptrdiff_t)sizeof(T) * nx * -2, vec_re, vec_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave_ - p * dw), (ptrdiff_t)sizeof(T) * dw * -2, vec_w_re, vec_w_im, vl);
|
||||
auto vec_r1 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
|
||||
auto vec_i1 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
|
||||
|
||||
auto vec_r0 = __riscv_vfadd(vec_r2, vec_r1, vl);
|
||||
auto vec_i0 = __riscv_vfsub(vec_i2, vec_i1, vl);
|
||||
vec_r1 = __riscv_vfsub(vec_r2, vec_r1, vl);
|
||||
vec_i1 = __riscv_vfadd(vec_i2, vec_i1, vl);
|
||||
|
||||
vn_0.re += __riscv_vfmv_f(__riscv_vfredosum(vec_r0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
vn_0.im += __riscv_vfmv_f(__riscv_vfredosum(vec_i1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(a + p - 1), vec_r0, vec_i0, vl);
|
||||
rvv<T>::vsseg(reinterpret_cast<T*>(b + p - 1), vec_r1, vec_i1, vl);
|
||||
}
|
||||
}
|
||||
|
||||
v[0] = vn_0;
|
||||
|
||||
for( p = 1, k = nx; p <= factor2; p++, k += nx )
|
||||
{
|
||||
Complex<T> s0 = v_0, s1 = v_0;
|
||||
dd = dw_f*p;
|
||||
|
||||
vl = __riscv_vsetvlmax_e32mf2();
|
||||
auto vec_dd = __riscv_vid_v_u32mf2(vl);
|
||||
vec_dd = __riscv_vmul(vec_dd, dd, vl);
|
||||
vec_dd = __riscv_vremu(vec_dd, tab_size, vl);
|
||||
|
||||
for( q = 0; q < factor2; q += vl )
|
||||
{
|
||||
vl = rvv<T>::setvl(factor2 - q);
|
||||
|
||||
auto vec_d = __riscv_vadd(vec_dd, (q + 1) * dd % tab_size, vl);
|
||||
auto vmask = __riscv_vmsgeu(vec_d, tab_size, vl);
|
||||
vec_d = __riscv_vsub_mu(vmask, vec_d, vec_d, tab_size, vl);
|
||||
vec_d = __riscv_vmul(vec_d, sizeof(T) * 2, vl);
|
||||
|
||||
auto vec_w = __riscv_vloxei32(reinterpret_cast<const T*>(wave), vec_d, vl);
|
||||
VT vec_a_re, vec_a_im, vec_b_re, vec_b_im;
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(a + q), sizeof(T) * 2, vec_a_re, vec_a_im, vl);
|
||||
rvv<T>::vlsseg(reinterpret_cast<const T*>(b + q), sizeof(T) * 2, vec_b_re, vec_b_im, vl);
|
||||
auto vec_r0 = __riscv_vfmul(vec_w, vec_a_re, vl);
|
||||
auto vec_r1 = __riscv_vfmul(vec_w, vec_b_im, vl);
|
||||
|
||||
vec_w = __riscv_vloxei32(reinterpret_cast<const T*>(wave) + 1, vec_d, vl);
|
||||
auto vec_i0 = __riscv_vfmul(vec_w, vec_a_im, vl);
|
||||
auto vec_i1 = __riscv_vfmul(vec_w, vec_b_re, vl);
|
||||
|
||||
T r0 = __riscv_vfmv_f(__riscv_vfredosum(vec_r0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
T i0 = __riscv_vfmv_f(__riscv_vfredosum(vec_i0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
T r1 = __riscv_vfmv_f(__riscv_vfredosum(vec_r1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
T i1 = __riscv_vfmv_f(__riscv_vfredosum(vec_i1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
|
||||
|
||||
s1.re += r0 + i0; s0.re += r0 - i0;
|
||||
s1.im += r1 - i1; s0.im += r1 + i1;
|
||||
}
|
||||
|
||||
v[k] = s0;
|
||||
v[n-k] = s1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( scale != 1 )
|
||||
{
|
||||
T re_scale = scale, im_scale = scale;
|
||||
if( isInverse )
|
||||
im_scale = -im_scale;
|
||||
|
||||
for( i = 0; i < len; i += vl )
|
||||
{
|
||||
vl = TabType::setvl(len - i);
|
||||
auto vec_src_re = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i), sizeof(T) * 2, vl);
|
||||
auto vec_src_im = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i) + 1, sizeof(T) * 2, vl);
|
||||
vec_src_re = __riscv_vfmul(vec_src_re, re_scale, vl);
|
||||
vec_src_im = __riscv_vfmul(vec_src_im, im_scale, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i), sizeof(T) * 2, vec_src_re, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
|
||||
}
|
||||
}
|
||||
else if( isInverse )
|
||||
{
|
||||
for( i = 0; i < len; i += vl )
|
||||
{
|
||||
vl = TabType::setvl(len - i);
|
||||
auto vec_src_im = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i) + 1, sizeof(T) * 2, vl);
|
||||
vec_src_im = __riscv_vfneg(vec_src_im, vl);
|
||||
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int dft(const uchar* src, uchar* dst, int depth, int nf, int *factors, double scale, int* itab, void* wave,
|
||||
int tab_size, int n, bool isInverse, bool noPermute)
|
||||
{
|
||||
if( n == 0 )
|
||||
return CV_HAL_ERROR_OK;
|
||||
|
||||
switch( depth )
|
||||
{
|
||||
case CV_32F:
|
||||
return dft(reinterpret_cast<const Complex<float>*>(src), reinterpret_cast<Complex<float>*>(dst), nf, factors, (float)scale,
|
||||
itab, reinterpret_cast<const Complex<float>*>(wave), tab_size, n, isInverse, noPermute);
|
||||
case CV_64F:
|
||||
return dft(reinterpret_cast<const Complex<double>*>(src), reinterpret_cast<Complex<double>*>(dst), nf, factors, (double)scale,
|
||||
itab, reinterpret_cast<const Complex<double>*>(wave), tab_size, n, isInverse, noPermute);
|
||||
}
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Vendored
+202
@@ -0,0 +1,202 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level
|
||||
// directory of this distribution and at http://opencv.org/license.html.
|
||||
#pragma once
|
||||
|
||||
#include <riscv_vector.h>
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
#undef cv_hal_exp32f
|
||||
#define cv_hal_exp32f cv::cv_hal_rvv::exp32f
|
||||
#undef cv_hal_exp64f
|
||||
#define cv_hal_exp64f cv::cv_hal_rvv::exp64f
|
||||
|
||||
namespace detail {
|
||||
|
||||
static constexpr size_t exp_scale = 6;
|
||||
static constexpr size_t exp_tab_size = 1 << exp_scale;
|
||||
static constexpr size_t exp_mask = exp_tab_size - 1;
|
||||
|
||||
static constexpr double exp_prescale = 1.4426950408889634073599246810019 * (1 << exp_scale);
|
||||
static constexpr double exp_postscale = 1. / (1 << exp_scale);
|
||||
// log10(DBL_MAX) < 3000
|
||||
static constexpr double exp_max_val = (3000. * (1 << exp_scale)) / exp_prescale;
|
||||
static constexpr double exp_min_val = -exp_max_val;
|
||||
|
||||
static constexpr double exp32f_a0 = .9670371139572337719125840413672004409288e-2;
|
||||
static constexpr double exp32f_a1 = .5550339366753125211915322047004666939128e-1 / exp32f_a0;
|
||||
static constexpr double exp32f_a2 = .2402265109513301490103372422686535526573 / exp32f_a0;
|
||||
static constexpr double exp32f_a3 = .6931471805521448196800669615864773144641 / exp32f_a0;
|
||||
static constexpr double exp32f_a4 = 1.000000000000002438532970795181890933776 / exp32f_a0;
|
||||
|
||||
static constexpr double exp64f_a0 = .13369713757180123244806654839424e-2 / exp32f_a0;
|
||||
static constexpr double exp64f_a1 = .96180973140732918010002372686186e-2 / exp32f_a0;
|
||||
static constexpr double exp64f_a2 = .55504108793649567998466049042729e-1 / exp32f_a0;
|
||||
static constexpr double exp64f_a3 = .24022650695886477918181338054308 / exp32f_a0;
|
||||
static constexpr double exp64f_a4 = .69314718055994546743029643825322 / exp32f_a0;
|
||||
static constexpr double exp64f_a5 = .99999999999999999998285227504999 / exp32f_a0;
|
||||
|
||||
#define EXP_TAB_VALUE \
|
||||
{ \
|
||||
1.0 * exp32f_a0, \
|
||||
1.0108892860517004600204097905619 * exp32f_a0, \
|
||||
1.0218971486541166782344801347833 * exp32f_a0, \
|
||||
1.0330248790212284225001082839705 * exp32f_a0, \
|
||||
1.0442737824274138403219664787399 * exp32f_a0, \
|
||||
1.0556451783605571588083413251529 * exp32f_a0, \
|
||||
1.0671404006768236181695211209928 * exp32f_a0, \
|
||||
1.0787607977571197937406800374385 * exp32f_a0, \
|
||||
1.0905077326652576592070106557607 * exp32f_a0, \
|
||||
1.1023825833078409435564142094256 * exp32f_a0, \
|
||||
1.1143867425958925363088129569196 * exp32f_a0, \
|
||||
1.126521618608241899794798643787 * exp32f_a0, \
|
||||
1.1387886347566916537038302838415 * exp32f_a0, \
|
||||
1.151189229952982705817759635202 * exp32f_a0, \
|
||||
1.1637248587775775138135735990922 * exp32f_a0, \
|
||||
1.1763969916502812762846457284838 * exp32f_a0, \
|
||||
1.1892071150027210667174999705605 * exp32f_a0, \
|
||||
1.2021567314527031420963969574978 * exp32f_a0, \
|
||||
1.2152473599804688781165202513388 * exp32f_a0, \
|
||||
1.2284805361068700056940089577928 * exp32f_a0, \
|
||||
1.2418578120734840485936774687266 * exp32f_a0, \
|
||||
1.2553807570246910895793906574423 * exp32f_a0, \
|
||||
1.2690509571917332225544190810323 * exp32f_a0, \
|
||||
1.2828700160787782807266697810215 * exp32f_a0, \
|
||||
1.2968395546510096659337541177925 * exp32f_a0, \
|
||||
1.3109612115247643419229917863308 * exp32f_a0, \
|
||||
1.3252366431597412946295370954987 * exp32f_a0, \
|
||||
1.3396675240533030053600306697244 * exp32f_a0, \
|
||||
1.3542555469368927282980147401407 * exp32f_a0, \
|
||||
1.3690024229745906119296011329822 * exp32f_a0, \
|
||||
1.3839098819638319548726595272652 * exp32f_a0, \
|
||||
1.3989796725383111402095281367152 * exp32f_a0, \
|
||||
1.4142135623730950488016887242097 * exp32f_a0, \
|
||||
1.4296133383919700112350657782751 * exp32f_a0, \
|
||||
1.4451808069770466200370062414717 * exp32f_a0, \
|
||||
1.4609177941806469886513028903106 * exp32f_a0, \
|
||||
1.476826145939499311386907480374 * exp32f_a0, \
|
||||
1.4929077282912648492006435314867 * exp32f_a0, \
|
||||
1.5091644275934227397660195510332 * exp32f_a0, \
|
||||
1.5255981507445383068512536895169 * exp32f_a0, \
|
||||
1.5422108254079408236122918620907 * exp32f_a0, \
|
||||
1.5590044002378369670337280894749 * exp32f_a0, \
|
||||
1.5759808451078864864552701601819 * exp32f_a0, \
|
||||
1.5931421513422668979372486431191 * exp32f_a0, \
|
||||
1.6104903319492543081795206673574 * exp32f_a0, \
|
||||
1.628027421857347766848218522014 * exp32f_a0, \
|
||||
1.6457554781539648445187567247258 * exp32f_a0, \
|
||||
1.6636765803267364350463364569764 * exp32f_a0, \
|
||||
1.6817928305074290860622509524664 * exp32f_a0, \
|
||||
1.7001063537185234695013625734975 * exp32f_a0, \
|
||||
1.7186192981224779156293443764563 * exp32f_a0, \
|
||||
1.7373338352737062489942020818722 * exp32f_a0, \
|
||||
1.7562521603732994831121606193753 * exp32f_a0, \
|
||||
1.7753764925265212525505592001993 * exp32f_a0, \
|
||||
1.7947090750031071864277032421278 * exp32f_a0, \
|
||||
1.8142521755003987562498346003623 * exp32f_a0, \
|
||||
1.8340080864093424634870831895883 * exp32f_a0, \
|
||||
1.8539791250833855683924530703377 * exp32f_a0, \
|
||||
1.8741676341102999013299989499544 * exp32f_a0, \
|
||||
1.8945759815869656413402186534269 * exp32f_a0, \
|
||||
1.9152065613971472938726112702958 * exp32f_a0, \
|
||||
1.9360617934922944505980559045667 * exp32f_a0, \
|
||||
1.9571441241754002690183222516269 * exp32f_a0, \
|
||||
1.9784560263879509682582499181312 * exp32f_a0, \
|
||||
}
|
||||
|
||||
static constexpr float exp_tab_32f[exp_tab_size] = EXP_TAB_VALUE;
|
||||
static constexpr double exp_tab_64f[exp_tab_size] = EXP_TAB_VALUE;
|
||||
|
||||
#undef EXP_TAB_VALUE
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline int exp32f(const float* src, float* dst, int _len)
|
||||
{
|
||||
size_t vl = __riscv_vsetvlmax_e32m4();
|
||||
auto exp_a2 = __riscv_vfmv_v_f_f32m4(detail::exp32f_a2, vl);
|
||||
auto exp_a3 = __riscv_vfmv_v_f_f32m4(detail::exp32f_a3, vl);
|
||||
auto exp_a4 = __riscv_vfmv_v_f_f32m4(detail::exp32f_a4, vl);
|
||||
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m4(len);
|
||||
auto x0 = __riscv_vle32_v_f32m4(src, vl);
|
||||
|
||||
x0 = __riscv_vfmax(x0, detail::exp_min_val, vl);
|
||||
x0 = __riscv_vfmin(x0, detail::exp_max_val, vl);
|
||||
x0 = __riscv_vfmul(x0, detail::exp_prescale, vl);
|
||||
|
||||
auto xi = __riscv_vfcvt_rtz_x_f_v_i32m4(x0, vl);
|
||||
x0 = __riscv_vfsub(x0, __riscv_vfcvt_f_x_v_f32m4(xi, vl), vl);
|
||||
x0 = __riscv_vfmul(x0, detail::exp_postscale, vl);
|
||||
|
||||
auto t = __riscv_vsra(xi, detail::exp_scale, vl);
|
||||
t = __riscv_vadd(t, 127, vl);
|
||||
t = __riscv_vmax(t, 0, vl);
|
||||
t = __riscv_vmin(t, 255, vl);
|
||||
auto buf = __riscv_vreinterpret_f32m4(__riscv_vsll(t, 23, vl));
|
||||
|
||||
auto _xi = __riscv_vreinterpret_u32m4(xi);
|
||||
_xi = __riscv_vsll(__riscv_vand(_xi, detail::exp_mask, vl), 2, vl);
|
||||
auto tab_v = __riscv_vluxei32(detail::exp_tab_32f, _xi, vl);
|
||||
|
||||
auto res = __riscv_vfmul(buf, tab_v, vl);
|
||||
auto xn = __riscv_vfadd(x0, detail::exp32f_a1, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a2, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a3, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a4, vl);
|
||||
|
||||
res = __riscv_vfmul(res, xn, vl);
|
||||
__riscv_vse32(dst, res, vl);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int exp64f(const double* src, double* dst, int _len)
|
||||
{
|
||||
size_t vl = __riscv_vsetvlmax_e64m4();
|
||||
// all vector registers are used up, so not load more constants
|
||||
auto exp_a2 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a2, vl);
|
||||
auto exp_a3 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a3, vl);
|
||||
auto exp_a4 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a4, vl);
|
||||
auto exp_a5 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a5, vl);
|
||||
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e64m4(len);
|
||||
auto x0 = __riscv_vle64_v_f64m4(src, vl);
|
||||
|
||||
x0 = __riscv_vfmax(x0, detail::exp_min_val, vl);
|
||||
x0 = __riscv_vfmin(x0, detail::exp_max_val, vl);
|
||||
x0 = __riscv_vfmul(x0, detail::exp_prescale, vl);
|
||||
|
||||
auto xi = __riscv_vfcvt_rtz_x_f_v_i64m4(x0, vl);
|
||||
x0 = __riscv_vfsub(x0, __riscv_vfcvt_f_x_v_f64m4(xi, vl), vl);
|
||||
x0 = __riscv_vfmul(x0, detail::exp_postscale, vl);
|
||||
|
||||
auto t = __riscv_vsra(xi, detail::exp_scale, vl);
|
||||
t = __riscv_vadd(t, 1023, vl);
|
||||
t = __riscv_vmax(t, 0, vl);
|
||||
t = __riscv_vmin(t, 2047, vl);
|
||||
auto buf = __riscv_vreinterpret_f64m4(__riscv_vsll(t, 52, vl));
|
||||
|
||||
auto _xi = __riscv_vreinterpret_u64m4(xi);
|
||||
_xi = __riscv_vsll(__riscv_vand(_xi, detail::exp_mask, vl), 3, vl);
|
||||
auto tab_v = __riscv_vluxei64(detail::exp_tab_64f, _xi, vl);
|
||||
|
||||
auto res = __riscv_vfmul(buf, tab_v, vl);
|
||||
auto xn = __riscv_vfadd(__riscv_vfmul(x0, detail::exp64f_a0, vl), detail::exp64f_a1, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a2, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a3, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a4, vl);
|
||||
xn = __riscv_vfmadd(xn, x0, exp_a5, vl);
|
||||
|
||||
res = __riscv_vfmul(res, xn, vl);
|
||||
__riscv_vse64(dst, res, vl);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}} // namespace cv::cv_hal_rvv
|
||||
+852
@@ -0,0 +1,852 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_FILTER_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_FILTER_HPP_INCLUDED
|
||||
|
||||
#include "../../imgproc/include/opencv2/imgproc/hal/interface.h"
|
||||
#include <riscv_vector.h>
|
||||
|
||||
struct cvhalFilter2D;
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
namespace filter {
|
||||
#undef cv_hal_filterInit
|
||||
#undef cv_hal_filter
|
||||
#undef cv_hal_filterFree
|
||||
#define cv_hal_filterInit cv::cv_hal_rvv::filter::filterInit
|
||||
#define cv_hal_filter cv::cv_hal_rvv::filter::filter
|
||||
#define cv_hal_filterFree cv::cv_hal_rvv::filter::filterFree
|
||||
|
||||
class FilterInvoker : public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
template<typename... Args>
|
||||
FilterInvoker(std::function<int(int, int, Args...)> _func, Args&&... args)
|
||||
{
|
||||
func = std::bind(_func, std::placeholders::_1, std::placeholders::_2, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
virtual void operator()(const Range& range) const override
|
||||
{
|
||||
func(range.start, range.end);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<int(int, int)> func;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
static inline int invoke(int start, int end, std::function<int(int, int, Args...)> func, Args&&... args)
|
||||
{
|
||||
cv::parallel_for_(Range(start + 1, end), FilterInvoker(func, std::forward<Args>(args)...), cv::getNumThreads());
|
||||
return func(start, start + 1, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static inline int borderInterpolate( int p, int len, int borderType )
|
||||
{
|
||||
if( (unsigned)p < (unsigned)len )
|
||||
;
|
||||
else if( borderType == BORDER_REPLICATE )
|
||||
p = p < 0 ? 0 : len - 1;
|
||||
else if( borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101 )
|
||||
{
|
||||
int delta = borderType == BORDER_REFLECT_101;
|
||||
if( len == 1 )
|
||||
return 0;
|
||||
do
|
||||
{
|
||||
if( p < 0 )
|
||||
p = -p - 1 + delta;
|
||||
else
|
||||
p = len - 1 - (p - len) - delta;
|
||||
}
|
||||
while( (unsigned)p >= (unsigned)len );
|
||||
}
|
||||
else if( borderType == BORDER_CONSTANT )
|
||||
p = -1;
|
||||
return p;
|
||||
}
|
||||
|
||||
struct Filter2D
|
||||
{
|
||||
const uchar* kernel_data;
|
||||
size_t kernel_step;
|
||||
int kernel_type;
|
||||
int kernel_width;
|
||||
int kernel_height;
|
||||
int src_type;
|
||||
int dst_type;
|
||||
int borderType;
|
||||
double delta;
|
||||
int anchor_x;
|
||||
int anchor_y;
|
||||
};
|
||||
|
||||
inline int filterInit(cvhalFilter2D** context, uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height, int /*max_width*/, int /*max_height*/, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool /*allowSubmatrix*/, bool /*allowInplace*/)
|
||||
{
|
||||
if (kernel_type != CV_32FC1 || src_type != CV_8UC4 || dst_type != CV_8UC4)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (kernel_width != kernel_height)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (kernel_width != 3 && kernel_width != 5)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if ((borderType & ~BORDER_ISOLATED) == BORDER_WRAP)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
anchor_x = anchor_x < 0 ? kernel_width / 2 : anchor_x;
|
||||
anchor_y = anchor_y < 0 ? kernel_height / 2 : anchor_y;
|
||||
*context = reinterpret_cast<cvhalFilter2D*>(new Filter2D{kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, src_type, dst_type, borderType, delta, anchor_x, anchor_y});
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
static void process3(int anchor, int left, int right, float delta, const float* kernel, const uchar* row0, const uchar* row1, const uchar* row2, uchar* dst)
|
||||
{
|
||||
int vl;
|
||||
for (int i = left; i < right; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m1(right - i);
|
||||
auto s0 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
auto s1 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
auto s2 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
auto s3 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
|
||||
auto addshift = [&](vfloat32m4_t a, vfloat32m4_t b, float k0, float k1, float k2, float r1, float r2) {
|
||||
a = __riscv_vfmacc(a, k0, b, vl);
|
||||
b = __riscv_vfslide1down(b, r1, vl);
|
||||
a = __riscv_vfmacc(a, k1, b, vl);
|
||||
b = __riscv_vfslide1down(b, r2, vl);
|
||||
return __riscv_vfmacc(a, k2, b, vl);
|
||||
};
|
||||
auto loadsrc = [&](const uchar* row, float k0, float k1, float k2) {
|
||||
if (!row) return;
|
||||
|
||||
const uchar* extra = row + (i - anchor) * 4;
|
||||
auto src = __riscv_vlseg4e8_v_u8m1x4(extra, vl);
|
||||
auto v0 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 0), vl), vl);
|
||||
auto v1 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 1), vl), vl);
|
||||
auto v2 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 2), vl), vl);
|
||||
auto v3 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 3), vl), vl);
|
||||
|
||||
s0 = addshift(s0, v0, k0, k1, k2, extra[vl * 4 ], extra[vl * 4 + 4]);
|
||||
s1 = addshift(s1, v1, k0, k1, k2, extra[vl * 4 + 1], extra[vl * 4 + 5]);
|
||||
s2 = addshift(s2, v2, k0, k1, k2, extra[vl * 4 + 2], extra[vl * 4 + 6]);
|
||||
s3 = addshift(s3, v3, k0, k1, k2, extra[vl * 4 + 3], extra[vl * 4 + 7]);
|
||||
};
|
||||
|
||||
loadsrc(row0, kernel[0], kernel[1], kernel[2]);
|
||||
loadsrc(row1, kernel[3], kernel[4], kernel[5]);
|
||||
loadsrc(row2, kernel[6], kernel[7], kernel[8]);
|
||||
vuint8m1x4_t val{};
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 0, __riscv_vnclipu(__riscv_vfncvt_xu(s0, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 1, __riscv_vnclipu(__riscv_vfncvt_xu(s1, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 2, __riscv_vnclipu(__riscv_vfncvt_xu(s2, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 3, __riscv_vnclipu(__riscv_vfncvt_xu(s3, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
__riscv_vsseg4e8(dst + i * 4, val, vl);
|
||||
}
|
||||
}
|
||||
|
||||
static void process5(int anchor, int left, int right, float delta, const float* kernel, const uchar* row0, const uchar* row1, const uchar* row2, const uchar* row3, const uchar* row4, uchar* dst)
|
||||
{
|
||||
int vl;
|
||||
for (int i = left; i < right; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m1(right - i);
|
||||
auto s0 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
auto s1 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
auto s2 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
auto s3 = __riscv_vfmv_v_f_f32m4(delta, vl);
|
||||
|
||||
auto addshift = [&](vfloat32m4_t a, vfloat32m4_t b, float k0, float k1, float k2, float k3, float k4, float r1, float r2, float r3, float r4) {
|
||||
a = __riscv_vfmacc(a, k0, b, vl);
|
||||
b = __riscv_vfslide1down(b, r1, vl);
|
||||
a = __riscv_vfmacc(a, k1, b, vl);
|
||||
b = __riscv_vfslide1down(b, r2, vl);
|
||||
a = __riscv_vfmacc(a, k2, b, vl);
|
||||
b = __riscv_vfslide1down(b, r3, vl);
|
||||
a = __riscv_vfmacc(a, k3, b, vl);
|
||||
b = __riscv_vfslide1down(b, r4, vl);
|
||||
return __riscv_vfmacc(a, k4, b, vl);
|
||||
};
|
||||
auto loadsrc = [&](const uchar* row, float k0, float k1, float k2, float k3, float k4) {
|
||||
if (!row) return;
|
||||
|
||||
auto src = __riscv_vlseg4e8_v_u8m1x4(row + (i - anchor) * 4, vl);
|
||||
auto v0 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 0), vl), vl);
|
||||
auto v1 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 1), vl), vl);
|
||||
auto v2 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 2), vl), vl);
|
||||
auto v3 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 3), vl), vl);
|
||||
|
||||
const uchar* extra = row + (i + vl - anchor) * 4;
|
||||
s0 = addshift(s0, v0, k0, k1, k2, k3, k4, *(extra ), *(extra + 4), *(extra + 8), *(extra + 12));
|
||||
s1 = addshift(s1, v1, k0, k1, k2, k3, k4, *(extra + 1), *(extra + 5), *(extra + 9), *(extra + 13));
|
||||
s2 = addshift(s2, v2, k0, k1, k2, k3, k4, *(extra + 2), *(extra + 6), *(extra + 10), *(extra + 14));
|
||||
s3 = addshift(s3, v3, k0, k1, k2, k3, k4, *(extra + 3), *(extra + 7), *(extra + 11), *(extra + 15));
|
||||
};
|
||||
|
||||
loadsrc(row0, kernel[ 0], kernel[ 1], kernel[ 2], kernel[ 3], kernel[ 4]);
|
||||
loadsrc(row1, kernel[ 5], kernel[ 6], kernel[ 7], kernel[ 8], kernel[ 9]);
|
||||
loadsrc(row2, kernel[10], kernel[11], kernel[12], kernel[13], kernel[14]);
|
||||
loadsrc(row3, kernel[15], kernel[16], kernel[17], kernel[18], kernel[19]);
|
||||
loadsrc(row4, kernel[20], kernel[21], kernel[22], kernel[23], kernel[24]);
|
||||
vuint8m1x4_t val{};
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 0, __riscv_vnclipu(__riscv_vfncvt_xu(s0, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 1, __riscv_vnclipu(__riscv_vfncvt_xu(s1, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 2, __riscv_vnclipu(__riscv_vfncvt_xu(s2, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
val = __riscv_vset_v_u8m1_u8m1x4(val, 3, __riscv_vnclipu(__riscv_vfncvt_xu(s3, vl), 0, __RISCV_VXRM_RNU, vl));
|
||||
__riscv_vsseg4e8(dst + i * 4, val, vl);
|
||||
}
|
||||
}
|
||||
|
||||
// the algorithm is copied from 3rdparty/carotene/src/convolution.cpp,
|
||||
// in the function void CAROTENE_NS::convolution
|
||||
template<int ksize>
|
||||
static inline int filter(int start, int end, Filter2D* data, const uchar* src_data, size_t src_step, uchar* dst_data, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
|
||||
{
|
||||
float kernel[ksize * ksize];
|
||||
for (int i = 0; i < ksize * ksize; i++)
|
||||
{
|
||||
kernel[i] = reinterpret_cast<const float*>(data->kernel_data + (i / ksize) * data->kernel_step)[i % ksize];
|
||||
}
|
||||
|
||||
constexpr int noval = std::numeric_limits<int>::max();
|
||||
auto access = [&](int x, int y) {
|
||||
int pi, pj;
|
||||
if (data->borderType & BORDER_ISOLATED)
|
||||
{
|
||||
pi = borderInterpolate(x - data->anchor_y, height, data->borderType & ~BORDER_ISOLATED);
|
||||
pj = borderInterpolate(y - data->anchor_x, width , data->borderType & ~BORDER_ISOLATED);
|
||||
pi = pi < 0 ? noval : pi;
|
||||
pj = pj < 0 ? noval : pj;
|
||||
}
|
||||
else
|
||||
{
|
||||
pi = borderInterpolate(offset_y + x - data->anchor_y, full_height, data->borderType);
|
||||
pj = borderInterpolate(offset_x + y - data->anchor_x, full_width , data->borderType);
|
||||
pi = pi < 0 ? noval : pi - offset_y;
|
||||
pj = pj < 0 ? noval : pj - offset_x;
|
||||
}
|
||||
return std::make_pair(pi, pj);
|
||||
};
|
||||
|
||||
auto process = [&](int x, int y) {
|
||||
float sum0, sum1, sum2, sum3;
|
||||
sum0 = sum1 = sum2 = sum3 = data->delta;
|
||||
for (int i = 0; i < ksize * ksize; i++)
|
||||
{
|
||||
auto p = access(x + i / ksize, y + i % ksize);
|
||||
if (p.first != noval && p.second != noval)
|
||||
{
|
||||
sum0 += kernel[i] * src_data[p.first * src_step + p.second * 4 ];
|
||||
sum1 += kernel[i] * src_data[p.first * src_step + p.second * 4 + 1];
|
||||
sum2 += kernel[i] * src_data[p.first * src_step + p.second * 4 + 2];
|
||||
sum3 += kernel[i] * src_data[p.first * src_step + p.second * 4 + 3];
|
||||
}
|
||||
}
|
||||
dst_data[(x * width + y) * 4 ] = std::max(0, std::min((int)std::round(sum0), (int)std::numeric_limits<uchar>::max()));
|
||||
dst_data[(x * width + y) * 4 + 1] = std::max(0, std::min((int)std::round(sum1), (int)std::numeric_limits<uchar>::max()));
|
||||
dst_data[(x * width + y) * 4 + 2] = std::max(0, std::min((int)std::round(sum2), (int)std::numeric_limits<uchar>::max()));
|
||||
dst_data[(x * width + y) * 4 + 3] = std::max(0, std::min((int)std::round(sum3), (int)std::numeric_limits<uchar>::max()));
|
||||
};
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
const int left = ksize - 1, right = width - (ksize - 1);
|
||||
if (left >= right)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
process(i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < left; j++)
|
||||
process(i, j);
|
||||
for (int j = right; j < width; j++)
|
||||
process(i, j);
|
||||
|
||||
const uchar* row0 = access(i , 0).first == noval ? nullptr : src_data + access(i , 0).first * src_step;
|
||||
const uchar* row1 = access(i + 1, 0).first == noval ? nullptr : src_data + access(i + 1, 0).first * src_step;
|
||||
const uchar* row2 = access(i + 2, 0).first == noval ? nullptr : src_data + access(i + 2, 0).first * src_step;
|
||||
if (ksize == 3)
|
||||
{
|
||||
process3(data->anchor_x, left, right, data->delta, kernel, row0, row1, row2, dst_data + i * width * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
const uchar* row3 = access(i + 3, 0).first == noval ? nullptr : src_data + access(i + 3, 0).first * src_step;
|
||||
const uchar* row4 = access(i + 4, 0).first == noval ? nullptr : src_data + access(i + 4, 0).first * src_step;
|
||||
process5(data->anchor_x, left, right, data->delta, kernel, row0, row1, row2, row3, row4, dst_data + i * width * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int filter(cvhalFilter2D* context, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
|
||||
{
|
||||
Filter2D* data = reinterpret_cast<Filter2D*>(context);
|
||||
std::vector<uchar> dst(width * height * 4);
|
||||
|
||||
int res = CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
switch (data->kernel_width)
|
||||
{
|
||||
case 3:
|
||||
res = invoke(0, height, {filter<3>}, data, src_data, src_step, dst.data(), width, height, full_width, full_height, offset_x, offset_y);
|
||||
break;
|
||||
case 5:
|
||||
res = invoke(0, height, {filter<5>}, data, src_data, src_step, dst.data(), width, height, full_width, full_height, offset_x, offset_y);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
std::copy(dst.data() + i * width * 4, dst.data() + (i + 1) * width * 4, dst_data + i * dst_step);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int filterFree(cvhalFilter2D* context)
|
||||
{
|
||||
delete reinterpret_cast<Filter2D*>(context);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
} // cv::cv_hal_rvv::filter
|
||||
|
||||
namespace sepFilter {
|
||||
#undef cv_hal_sepFilterInit
|
||||
#undef cv_hal_sepFilter
|
||||
#undef cv_hal_sepFilterFree
|
||||
#define cv_hal_sepFilterInit cv::cv_hal_rvv::sepFilter::sepFilterInit
|
||||
#define cv_hal_sepFilter cv::cv_hal_rvv::sepFilter::sepFilter
|
||||
#define cv_hal_sepFilterFree cv::cv_hal_rvv::sepFilter::sepFilterFree
|
||||
|
||||
struct sepFilter2D
|
||||
{
|
||||
int src_type;
|
||||
int dst_type;
|
||||
int kernel_type;
|
||||
const uchar* kernelx_data;
|
||||
int kernelx_length;
|
||||
const uchar* kernely_data;
|
||||
int kernely_length;
|
||||
int anchor_x;
|
||||
int anchor_y;
|
||||
double delta;
|
||||
int borderType;
|
||||
};
|
||||
|
||||
inline int sepFilterInit(cvhalFilter2D **context, int src_type, int dst_type, int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length, int anchor_x, int anchor_y, double delta, int borderType)
|
||||
{
|
||||
if (kernel_type != CV_32FC1 || src_type != CV_8UC1 || (dst_type != CV_16SC1 && dst_type != CV_32FC1))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (kernelx_length != kernely_length)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (kernelx_length != 3 && kernelx_length != 5)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if ((borderType & ~BORDER_ISOLATED) == BORDER_WRAP)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
anchor_x = anchor_x < 0 ? kernelx_length / 2 : anchor_x;
|
||||
anchor_y = anchor_y < 0 ? kernely_length / 2 : anchor_y;
|
||||
*context = reinterpret_cast<cvhalFilter2D*>(new sepFilter2D{src_type, dst_type, kernel_type, kernelx_data, kernelx_length, kernely_data, kernely_length, anchor_x, anchor_y, delta, borderType & ~BORDER_ISOLATED});
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
// the algorithm is copied from 3rdparty/carotene/src/separable_filter.hpp,
|
||||
// in the functor RowFilter3x3S16Generic and ColFilter3x3S16Generic
|
||||
template<int ksize>
|
||||
static inline int sepFilterRow(int start, int end, sepFilter2D* data, const uchar* src_data, size_t src_step, float* dst_data, int width, int full_width, int offset_x)
|
||||
{
|
||||
constexpr int noval = std::numeric_limits<int>::max();
|
||||
auto access = [&](int y) {
|
||||
int pj;
|
||||
if (data->borderType & BORDER_ISOLATED)
|
||||
{
|
||||
pj = filter::borderInterpolate(y - data->anchor_x, width, data->borderType & ~BORDER_ISOLATED);
|
||||
pj = pj < 0 ? noval : pj;
|
||||
}
|
||||
else
|
||||
{
|
||||
pj = filter::borderInterpolate(offset_x + y - data->anchor_x, full_width, data->borderType);
|
||||
pj = pj < 0 ? noval : pj - offset_x;
|
||||
}
|
||||
return pj;
|
||||
};
|
||||
|
||||
const float* kx = reinterpret_cast<const float*>(data->kernelx_data);
|
||||
auto process = [&](int x, int y) {
|
||||
float sum = 0;
|
||||
for (int i = 0; i < ksize; i++)
|
||||
{
|
||||
int p = access(y + i);
|
||||
if (p != noval)
|
||||
{
|
||||
sum += kx[i] * src_data[x * src_step + p];
|
||||
}
|
||||
}
|
||||
dst_data[x * width + y] = sum;
|
||||
};
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
const int left = ksize - 1, right = width - (ksize - 1);
|
||||
if (left >= right)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
process(i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < left; j++)
|
||||
process(i, j);
|
||||
for (int j = right; j < width; j++)
|
||||
process(i, j);
|
||||
|
||||
int vl;
|
||||
for (int j = left; j < right; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m2(right - j);
|
||||
const uchar* extra = src_data + i * src_step + j - data->anchor_x;
|
||||
auto sum = __riscv_vfmv_v_f_f32m8(0, vl);
|
||||
auto src = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vle8_v_u8m2(extra, vl), vl), vl);
|
||||
sum = __riscv_vfmacc(sum, kx[0], src, vl);
|
||||
src = __riscv_vfslide1down(src, extra[vl], vl);
|
||||
sum = __riscv_vfmacc(sum, kx[1], src, vl);
|
||||
src = __riscv_vfslide1down(src, extra[vl + 1], vl);
|
||||
sum = __riscv_vfmacc(sum, kx[2], src, vl);
|
||||
if (ksize == 5)
|
||||
{
|
||||
src = __riscv_vfslide1down(src, extra[vl + 2], vl);
|
||||
sum = __riscv_vfmacc(sum, kx[3], src, vl);
|
||||
src = __riscv_vfslide1down(src, extra[vl + 3], vl);
|
||||
sum = __riscv_vfmacc(sum, kx[4], src, vl);
|
||||
}
|
||||
__riscv_vse32(dst_data + i * width + j, sum, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
template<int ksize>
|
||||
static inline int sepFilterCol(int start, int end, sepFilter2D* data, const float* src_data, uchar* dst_data, size_t dst_step, int width, int height, int full_height, int offset_y)
|
||||
{
|
||||
constexpr int noval = std::numeric_limits<int>::max();
|
||||
auto access = [&](int x) {
|
||||
int pi;
|
||||
if (data->borderType & BORDER_ISOLATED)
|
||||
{
|
||||
pi = filter::borderInterpolate(x - data->anchor_y, height, data->borderType & ~BORDER_ISOLATED);
|
||||
pi = pi < 0 ? noval : pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
pi = filter::borderInterpolate(offset_y + x - data->anchor_y, full_height, data->borderType);
|
||||
pi = pi < 0 ? noval : pi - offset_y;
|
||||
}
|
||||
return pi;
|
||||
};
|
||||
|
||||
const float* ky = reinterpret_cast<const float*>(data->kernely_data);
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
const float* row0 = access(i ) == noval ? nullptr : src_data + access(i ) * width;
|
||||
const float* row1 = access(i + 1) == noval ? nullptr : src_data + access(i + 1) * width;
|
||||
const float* row2 = access(i + 2) == noval ? nullptr : src_data + access(i + 2) * width;
|
||||
const float* row3, *row4;
|
||||
if (ksize == 5)
|
||||
{
|
||||
row3 = access(i + 3) == noval ? nullptr : src_data + access(i + 3) * width;
|
||||
row4 = access(i + 4) == noval ? nullptr : src_data + access(i + 4) * width;
|
||||
}
|
||||
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m4(width - j);
|
||||
auto v0 = row0 ? __riscv_vle32_v_f32m4(row0 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
|
||||
auto v1 = row1 ? __riscv_vle32_v_f32m4(row1 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
|
||||
auto v2 = row2 ? __riscv_vle32_v_f32m4(row2 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
|
||||
auto sum = __riscv_vfmacc(__riscv_vfmacc(__riscv_vfmacc(__riscv_vfmv_v_f_f32m4(data->delta, vl), ky[0], v0, vl), ky[1], v1, vl), ky[2], v2, vl);
|
||||
|
||||
if (ksize == 5)
|
||||
{
|
||||
auto v3 = row3 ? __riscv_vle32_v_f32m4(row3 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
|
||||
auto v4 = row4 ? __riscv_vle32_v_f32m4(row4 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
|
||||
sum = __riscv_vfmacc(__riscv_vfmacc(sum, ky[3], v3, vl), ky[4], v4, vl);
|
||||
}
|
||||
if (data->dst_type == CV_16SC1)
|
||||
{
|
||||
__riscv_vse16(reinterpret_cast<short*>(dst_data + i * dst_step) + j, __riscv_vfncvt_x(sum, vl), vl);
|
||||
}
|
||||
else
|
||||
{
|
||||
__riscv_vse32(reinterpret_cast<float*>(dst_data + i * dst_step) + j, sum, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int sepFilter(cvhalFilter2D *context, uchar *src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
|
||||
{
|
||||
sepFilter2D* data = reinterpret_cast<sepFilter2D*>(context);
|
||||
const int padding = data->kernelx_length - 1;
|
||||
std::vector<float> _result(width * (height + 2 * padding));
|
||||
float* result = _result.data() + width * padding;
|
||||
|
||||
int res = CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
switch (data->kernelx_length)
|
||||
{
|
||||
case 3:
|
||||
res = filter::invoke(-std::min(offset_y, padding), height + std::min(full_height - height - offset_y, padding), {sepFilterRow<3>}, data, src_data, src_step, result, width, full_width, offset_x);
|
||||
break;
|
||||
case 5:
|
||||
res = filter::invoke(-std::min(offset_y, padding), height + std::min(full_height - height - offset_y, padding), {sepFilterRow<5>}, data, src_data, src_step, result, width, full_width, offset_x);
|
||||
break;
|
||||
}
|
||||
if (res == CV_HAL_ERROR_NOT_IMPLEMENTED)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
switch (data->kernelx_length)
|
||||
{
|
||||
case 3:
|
||||
return filter::invoke(0, height, {sepFilterCol<3>}, data, result, dst_data, dst_step, width, height, full_height, offset_y);
|
||||
case 5:
|
||||
return filter::invoke(0, height, {sepFilterCol<5>}, data, result, dst_data, dst_step, width, height, full_height, offset_y);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
inline int sepFilterFree(cvhalFilter2D* context)
|
||||
{
|
||||
delete reinterpret_cast<sepFilter2D*>(context);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
} // cv::cv_hal_rvv::sepFilter
|
||||
|
||||
namespace morph {
|
||||
#undef cv_hal_morphInit
|
||||
#undef cv_hal_morph
|
||||
#undef cv_hal_morphFree
|
||||
#define cv_hal_morphInit cv::cv_hal_rvv::morph::morphInit
|
||||
#define cv_hal_morph cv::cv_hal_rvv::morph::morph
|
||||
#define cv_hal_morphFree cv::cv_hal_rvv::morph::morphFree
|
||||
|
||||
struct Morph2D
|
||||
{
|
||||
int operation;
|
||||
int src_type;
|
||||
int dst_type;
|
||||
int kernel_type;
|
||||
uchar *kernel_data;
|
||||
size_t kernel_step;
|
||||
int kernel_width;
|
||||
int kernel_height;
|
||||
int anchor_x;
|
||||
int anchor_y;
|
||||
int borderType;
|
||||
const uchar* borderValue;
|
||||
};
|
||||
|
||||
inline int morphInit(cvhalFilter2D** context, int operation, int src_type, int dst_type, int /*max_width*/, int /*max_height*/, int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, int borderType, const double borderValue[4], int iterations, bool /*allowSubmatrix*/, bool /*allowInplace*/)
|
||||
{
|
||||
if (kernel_type != CV_8UC1 || src_type != dst_type)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (src_type != CV_8UC1 && src_type != CV_8UC4)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (kernel_width != kernel_height || kernel_width != 3)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (iterations != 1)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if (operation != CV_HAL_MORPH_ERODE && operation != CV_HAL_MORPH_DILATE)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
if ((borderType & ~BORDER_ISOLATED) == BORDER_WRAP)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
uchar* borderV;
|
||||
if (src_type == CV_8UC1)
|
||||
{
|
||||
borderV = new uchar{static_cast<uchar>(borderValue[0])};
|
||||
if (operation == CV_HAL_MORPH_DILATE && borderValue[0] == DBL_MAX)
|
||||
borderV[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
borderV = new uchar[4]{static_cast<uchar>(borderValue[0]), static_cast<uchar>(borderValue[1]), static_cast<uchar>(borderValue[2]), static_cast<uchar>(borderValue[3])};
|
||||
if (operation == CV_HAL_MORPH_DILATE)
|
||||
{
|
||||
if (borderValue[0] == DBL_MAX)
|
||||
borderV[0] = 0;
|
||||
if (borderValue[1] == DBL_MAX)
|
||||
borderV[1] = 0;
|
||||
if (borderValue[2] == DBL_MAX)
|
||||
borderV[2] = 0;
|
||||
if (borderValue[3] == DBL_MAX)
|
||||
borderV[3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
anchor_x = anchor_x < 0 ? kernel_width / 2 : anchor_x;
|
||||
anchor_y = anchor_y < 0 ? kernel_height / 2 : anchor_y;
|
||||
*context = reinterpret_cast<cvhalFilter2D*>(new Morph2D{operation, src_type, dst_type, kernel_type, kernel_data, kernel_step, kernel_width, kernel_height, anchor_x, anchor_y, borderType, borderV});
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
template<int op> struct rvv;
|
||||
template<> struct rvv<CV_HAL_MORPH_ERODE>
|
||||
{
|
||||
static inline uchar init() { return std::numeric_limits<uchar>::max(); }
|
||||
static inline uchar mop(uchar a, uchar b) { return a < b ? a : b; }
|
||||
static inline vuint8m4_t vop(vuint8m4_t a, vuint8m4_t b, size_t c) { return __riscv_vminu(a, b, c); }
|
||||
static inline vuint8m4_t vop(vuint8m4_t a, uchar b, size_t c) { return __riscv_vminu(a, b, c); }
|
||||
};
|
||||
template<> struct rvv<CV_HAL_MORPH_DILATE>
|
||||
{
|
||||
static inline uchar init() { return std::numeric_limits<uchar>::min(); }
|
||||
static inline uchar mop(uchar a, uchar b) { return a > b ? a : b; }
|
||||
static inline vuint8m4_t vop(vuint8m4_t a, vuint8m4_t b, size_t c) { return __riscv_vmaxu(a, b, c); }
|
||||
static inline vuint8m4_t vop(vuint8m4_t a, uchar b, size_t c) { return __riscv_vmaxu(a, b, c); }
|
||||
};
|
||||
|
||||
// the algorithm is copied from 3rdparty/carotene/src/morph.cpp,
|
||||
// in the function template void morph3x3
|
||||
template<int op>
|
||||
static inline int morph(int start, int end, Morph2D* data, const uchar* src_data, size_t src_step, uchar* dst_data, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
|
||||
{
|
||||
bool kernel[9];
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
kernel[i] = data->kernel_data[(i / 3) * data->kernel_step + i % 3] != 0;
|
||||
}
|
||||
|
||||
constexpr int noval = std::numeric_limits<int>::max();
|
||||
auto access = [&](int x, int y) {
|
||||
int pi, pj;
|
||||
if (data->borderType & BORDER_ISOLATED)
|
||||
{
|
||||
pi = filter::borderInterpolate(x - data->anchor_y, height, data->borderType & ~BORDER_ISOLATED);
|
||||
pj = filter::borderInterpolate(y - data->anchor_x, width , data->borderType & ~BORDER_ISOLATED);
|
||||
pi = pi < 0 ? noval : pi;
|
||||
pj = pj < 0 ? noval : pj;
|
||||
}
|
||||
else
|
||||
{
|
||||
pi = filter::borderInterpolate(offset_y + x - data->anchor_y, full_height, data->borderType);
|
||||
pj = filter::borderInterpolate(offset_x + y - data->anchor_x, full_width , data->borderType);
|
||||
pi = pi < 0 ? noval : pi - offset_y;
|
||||
pj = pj < 0 ? noval : pj - offset_x;
|
||||
}
|
||||
return std::make_pair(pi, pj);
|
||||
};
|
||||
|
||||
auto process = [&](int x, int y) {
|
||||
if (data->src_type == CV_8UC1)
|
||||
{
|
||||
uchar val = rvv<op>::init();
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
if (kernel[i])
|
||||
{
|
||||
auto p = access(x + i / 3, y + i % 3);
|
||||
if (p.first != noval && p.second != noval)
|
||||
{
|
||||
val = rvv<op>::mop(val, src_data[p.first * src_step + p.second]);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = rvv<op>::mop(val, data->borderValue[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_data[x * width + y] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar val0, val1, val2, val3;
|
||||
val0 = val1 = val2 = val3 = rvv<op>::init();
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
if (kernel[i])
|
||||
{
|
||||
auto p = access(x + i / 3, y + i % 3);
|
||||
if (p.first != noval && p.second != noval)
|
||||
{
|
||||
val0 = rvv<op>::mop(val0, src_data[p.first * src_step + p.second * 4 ]);
|
||||
val1 = rvv<op>::mop(val1, src_data[p.first * src_step + p.second * 4 + 1]);
|
||||
val2 = rvv<op>::mop(val2, src_data[p.first * src_step + p.second * 4 + 2]);
|
||||
val3 = rvv<op>::mop(val3, src_data[p.first * src_step + p.second * 4 + 3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
val0 = rvv<op>::mop(val0, data->borderValue[0]);
|
||||
val1 = rvv<op>::mop(val1, data->borderValue[1]);
|
||||
val2 = rvv<op>::mop(val2, data->borderValue[2]);
|
||||
val3 = rvv<op>::mop(val3, data->borderValue[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_data[(x * width + y) * 4 ] = val0;
|
||||
dst_data[(x * width + y) * 4 + 1] = val1;
|
||||
dst_data[(x * width + y) * 4 + 2] = val2;
|
||||
dst_data[(x * width + y) * 4 + 3] = val3;
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
const int left = 2, right = width - 2;
|
||||
if (left >= right)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
process(i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < left; j++)
|
||||
process(i, j);
|
||||
for (int j = right; j < width; j++)
|
||||
process(i, j);
|
||||
|
||||
const uchar* row0 = access(i , 0).first == noval ? nullptr : src_data + access(i , 0).first * src_step;
|
||||
const uchar* row1 = access(i + 1, 0).first == noval ? nullptr : src_data + access(i + 1, 0).first * src_step;
|
||||
const uchar* row2 = access(i + 2, 0).first == noval ? nullptr : src_data + access(i + 2, 0).first * src_step;
|
||||
if (data->src_type == CV_8UC1)
|
||||
{
|
||||
int vl;
|
||||
for (int j = left; j < right; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(right - j);
|
||||
auto m0 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
|
||||
auto loadsrc = [&](const uchar* row, bool k0, bool k1, bool k2) {
|
||||
if (!row)
|
||||
{
|
||||
m0 = rvv<op>::vop(m0, data->borderValue[0], vl);
|
||||
return;
|
||||
}
|
||||
|
||||
const uchar* extra = row + j - data->anchor_x;
|
||||
auto v0 = __riscv_vle8_v_u8m4(extra, vl);
|
||||
|
||||
if (k0) m0 = rvv<op>::vop(m0, v0, vl);
|
||||
v0 = __riscv_vslide1down(v0, extra[vl], vl);
|
||||
if (k1) m0 = rvv<op>::vop(m0, v0, vl);
|
||||
if (!k2) return;
|
||||
v0 = __riscv_vslide1down(v0, extra[vl + 1], vl);
|
||||
m0 = rvv<op>::vop(m0, v0, vl);
|
||||
};
|
||||
|
||||
loadsrc(row0, kernel[0], kernel[1], kernel[2]);
|
||||
loadsrc(row1, kernel[3], kernel[4], kernel[5]);
|
||||
loadsrc(row2, kernel[6], kernel[7], kernel[8]);
|
||||
__riscv_vse8(dst_data + i * width + j, m0, vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int vl, vl0, vl1;
|
||||
for (int j = left; j < right; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(right - j);
|
||||
vl0 = std::min(vl, (int)__riscv_vlenb() * 2);
|
||||
vl1 = vl - vl0;
|
||||
auto m0 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
|
||||
auto m1 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
|
||||
auto m2 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
|
||||
auto m3 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
|
||||
|
||||
auto opshift = [&](vuint8m4_t a, vuint8m4_t b, bool k0, bool k1, bool k2, uchar r1, uchar r2) {
|
||||
if (k0) a = rvv<op>::vop(a, b, vl);
|
||||
b = __riscv_vslide1down(b, r1, vl);
|
||||
if (k1) a = rvv<op>::vop(a, b, vl);
|
||||
if (!k2) return a;
|
||||
b = __riscv_vslide1down(b, r2, vl);
|
||||
return rvv<op>::vop(a, b, vl);
|
||||
};
|
||||
auto loadsrc = [&](const uchar* row, bool k0, bool k1, bool k2) {
|
||||
if (!row)
|
||||
{
|
||||
m0 = rvv<op>::vop(m0, data->borderValue[0], vl);
|
||||
m1 = rvv<op>::vop(m1, data->borderValue[1], vl);
|
||||
m2 = rvv<op>::vop(m2, data->borderValue[2], vl);
|
||||
m3 = rvv<op>::vop(m3, data->borderValue[3], vl);
|
||||
return;
|
||||
}
|
||||
|
||||
vuint8m4_t v0{}, v1{}, v2{}, v3{};
|
||||
const uchar* extra = row + (j - data->anchor_x) * 4;
|
||||
auto src = __riscv_vlseg4e8_v_u8m2x4(extra, vl0);
|
||||
v0 = __riscv_vset_v_u8m2_u8m4(v0, 0, __riscv_vget_v_u8m2x4_u8m2(src, 0));
|
||||
v1 = __riscv_vset_v_u8m2_u8m4(v1, 0, __riscv_vget_v_u8m2x4_u8m2(src, 1));
|
||||
v2 = __riscv_vset_v_u8m2_u8m4(v2, 0, __riscv_vget_v_u8m2x4_u8m2(src, 2));
|
||||
v3 = __riscv_vset_v_u8m2_u8m4(v3, 0, __riscv_vget_v_u8m2x4_u8m2(src, 3));
|
||||
src = __riscv_vlseg4e8_v_u8m2x4(extra + vl0 * 4, vl1);
|
||||
v0 = __riscv_vset_v_u8m2_u8m4(v0, 1, __riscv_vget_v_u8m2x4_u8m2(src, 0));
|
||||
v1 = __riscv_vset_v_u8m2_u8m4(v1, 1, __riscv_vget_v_u8m2x4_u8m2(src, 1));
|
||||
v2 = __riscv_vset_v_u8m2_u8m4(v2, 1, __riscv_vget_v_u8m2x4_u8m2(src, 2));
|
||||
v3 = __riscv_vset_v_u8m2_u8m4(v3, 1, __riscv_vget_v_u8m2x4_u8m2(src, 3));
|
||||
|
||||
m0 = opshift(m0, v0, k0, k1, k2, extra[vl * 4 ], extra[vl * 4 + 4]);
|
||||
m1 = opshift(m1, v1, k0, k1, k2, extra[vl * 4 + 1], extra[vl * 4 + 5]);
|
||||
m2 = opshift(m2, v2, k0, k1, k2, extra[vl * 4 + 2], extra[vl * 4 + 6]);
|
||||
m3 = opshift(m3, v3, k0, k1, k2, extra[vl * 4 + 3], extra[vl * 4 + 7]);
|
||||
};
|
||||
|
||||
loadsrc(row0, kernel[0], kernel[1], kernel[2]);
|
||||
loadsrc(row1, kernel[3], kernel[4], kernel[5]);
|
||||
loadsrc(row2, kernel[6], kernel[7], kernel[8]);
|
||||
vuint8m2x4_t val{};
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 0, __riscv_vget_v_u8m4_u8m2(m0, 0));
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 1, __riscv_vget_v_u8m4_u8m2(m1, 0));
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 2, __riscv_vget_v_u8m4_u8m2(m2, 0));
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 3, __riscv_vget_v_u8m4_u8m2(m3, 0));
|
||||
__riscv_vsseg4e8(dst_data + (i * width + j) * 4, val, vl0);
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 0, __riscv_vget_v_u8m4_u8m2(m0, 1));
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 1, __riscv_vget_v_u8m4_u8m2(m1, 1));
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 2, __riscv_vget_v_u8m4_u8m2(m2, 1));
|
||||
val = __riscv_vset_v_u8m2_u8m2x4(val, 3, __riscv_vget_v_u8m4_u8m2(m3, 1));
|
||||
__riscv_vsseg4e8(dst_data + (i * width + j + vl0) * 4, val, vl1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int morph(cvhalFilter2D* context, uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step, int width, int height, int src_full_width, int src_full_height, int src_roi_x, int src_roi_y, int /*dst_full_width*/, int /*dst_full_height*/, int /*dst_roi_x*/, int /*dst_roi_y*/)
|
||||
{
|
||||
Morph2D* data = reinterpret_cast<Morph2D*>(context);
|
||||
int cn = data->src_type == CV_8UC1 ? 1 : 4;
|
||||
std::vector<uchar> dst(width * height * cn);
|
||||
|
||||
int res = CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
switch (data->operation)
|
||||
{
|
||||
case CV_HAL_MORPH_ERODE:
|
||||
res = filter::invoke(0, height, {morph<CV_HAL_MORPH_ERODE>}, data, src_data, src_step, dst.data(), width, height, src_full_width, src_full_height, src_roi_x, src_roi_y);
|
||||
break;
|
||||
case CV_HAL_MORPH_DILATE:
|
||||
res = filter::invoke(0, height, {morph<CV_HAL_MORPH_DILATE>}, data, src_data, src_step, dst.data(), width, height, src_full_width, src_full_height, src_roi_x, src_roi_y);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
std::copy(dst.data() + i * width * cn, dst.data() + (i + 1) * width * cn, dst_data + i * dst_step);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int morphFree(cvhalFilter2D* context)
|
||||
{
|
||||
delete reinterpret_cast<Morph2D*>(context)->borderValue;
|
||||
delete reinterpret_cast<Morph2D*>(context);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
} // cv::cv_hal_rvv::morph
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
+33
-56
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <riscv_vector.h>
|
||||
#include <opencv2/core/base.hpp>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
@@ -14,62 +14,33 @@ namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
struct FlipVlen256
|
||||
{
|
||||
using TableElemType = uchar;
|
||||
using TableType = vuint8m8_t;
|
||||
using SrcType = RVV_U8M8;
|
||||
using TabType = RVV_U8M8;
|
||||
using TabVecType = typename TabType::VecType;
|
||||
|
||||
static inline size_t setvlmax()
|
||||
static inline void gather(const uchar* src, TabVecType tab, uchar* dst, size_t vl)
|
||||
{
|
||||
return __riscv_vsetvlmax_e8m8();
|
||||
}
|
||||
|
||||
static inline TableType vid(size_t vl)
|
||||
{
|
||||
return __riscv_vid_v_u8m8(vl);
|
||||
}
|
||||
|
||||
static inline TableType loadTable(const TableElemType* ptr, size_t vl)
|
||||
{
|
||||
return __riscv_vle8_v_u8m8(ptr, vl);
|
||||
}
|
||||
|
||||
static inline void gather(const uchar* src, TableType tab, uchar* dst, size_t vl)
|
||||
{
|
||||
auto v = __riscv_vle8_v_u8m8(src, vl);
|
||||
__riscv_vse8(dst, __riscv_vrgather(v, tab, vl), vl);
|
||||
auto src_v = SrcType::vload(src, vl);
|
||||
SrcType::vstore(dst, __riscv_vrgather(src_v, tab, vl), vl);
|
||||
}
|
||||
};
|
||||
|
||||
struct FlipVlen512
|
||||
struct FlipVlen512 : RVV_U8M8
|
||||
{
|
||||
using TableElemType = uint16_t;
|
||||
using TableType = vuint16m8_t;
|
||||
using SrcType = RVV_U8M4;
|
||||
using TabType = RVV_U16M8;
|
||||
using TabVecType = typename TabType::VecType;
|
||||
|
||||
static inline size_t setvlmax()
|
||||
static inline void gather(const uchar* src, TabVecType tab, uchar* dst, size_t vl)
|
||||
{
|
||||
return __riscv_vsetvlmax_e8m4();
|
||||
}
|
||||
|
||||
static inline TableType vid(size_t vl)
|
||||
{
|
||||
return __riscv_vid_v_u16m8(vl);
|
||||
}
|
||||
|
||||
static inline TableType loadTable(const TableElemType* ptr, size_t vl)
|
||||
{
|
||||
return __riscv_vle16_v_u16m8(ptr, vl);
|
||||
}
|
||||
|
||||
static inline void gather(const uchar* src, TableType tab, uchar* dst, size_t vl)
|
||||
{
|
||||
auto v = __riscv_vle8_v_u8m4(src, vl);
|
||||
__riscv_vse8(dst, __riscv_vrgatherei16(v, tab, vl), vl);
|
||||
auto src_v = SrcType::vload(src, vl);
|
||||
SrcType::vstore(dst, __riscv_vrgatherei16(src_v, tab, vl), vl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline void flipFillBuffer(cv::AutoBuffer<T>& _buf, size_t len, int esz)
|
||||
inline void flipFillBuffer(T* buf, size_t len, int esz)
|
||||
{
|
||||
T* buf = _buf.data();
|
||||
for (int i = (int)len - esz; i >= 0; i -= esz, buf += esz)
|
||||
for (int j = 0; j < esz; j++)
|
||||
buf[j] = (T)(i + j);
|
||||
@@ -107,7 +78,9 @@ inline void flipX(int esz,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FlipVlen>
|
||||
template <typename FlipVlen,
|
||||
typename SrcType = typename FlipVlen::SrcType,
|
||||
typename TabType = typename FlipVlen::TabType>
|
||||
inline void flipY(int esz,
|
||||
const uchar* src_data,
|
||||
size_t src_step,
|
||||
@@ -117,15 +90,16 @@ inline void flipY(int esz,
|
||||
size_t dst_step)
|
||||
{
|
||||
size_t w = (size_t)src_width * esz;
|
||||
size_t vl = std::min(FlipVlen::setvlmax() / esz * esz, w);
|
||||
typename FlipVlen::TableType tab_v;
|
||||
size_t vl = std::min(SrcType::setvlmax() / esz * esz, w);
|
||||
typename TabType::VecType tab_v;
|
||||
if (esz == 1)
|
||||
tab_v = __riscv_vrsub(FlipVlen::vid(vl), vl - 1, vl);
|
||||
tab_v = __riscv_vrsub(TabType::vid(vl), vl - 1, vl);
|
||||
else
|
||||
{
|
||||
cv::AutoBuffer<typename FlipVlen::TableElemType> buf(vl);
|
||||
// max vlen supported is 1024 (vlmax of u8m4 for vlen 1024 is 512)
|
||||
typename TabType::ElemType buf[512];
|
||||
flipFillBuffer(buf, vl, esz);
|
||||
tab_v = FlipVlen::loadTable(buf.data(), vl);
|
||||
tab_v = TabType::vload(buf, vl);
|
||||
}
|
||||
if (vl == w)
|
||||
for (; src_height; src_height--, src_data += src_step, dst_data += dst_step)
|
||||
@@ -143,7 +117,9 @@ inline void flipY(int esz,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FlipVlen>
|
||||
template <typename FlipVlen,
|
||||
typename SrcType = typename FlipVlen::SrcType,
|
||||
typename TabType = typename FlipVlen::TabType>
|
||||
inline void flipXY(int esz,
|
||||
const uchar* src_data,
|
||||
size_t src_step,
|
||||
@@ -153,15 +129,16 @@ inline void flipXY(int esz,
|
||||
size_t dst_step)
|
||||
{
|
||||
size_t w = (size_t)src_width * esz;
|
||||
size_t vl = std::min(FlipVlen::setvlmax() / esz * esz, w);
|
||||
typename FlipVlen::TableType tab_v;
|
||||
size_t vl = std::min(SrcType::setvlmax() / esz * esz, w);
|
||||
typename TabType::VecType tab_v;
|
||||
if (esz == 1)
|
||||
tab_v = __riscv_vrsub(FlipVlen::vid(vl), vl - 1, vl);
|
||||
tab_v = __riscv_vrsub(TabType::vid(vl), vl - 1, vl);
|
||||
else
|
||||
{
|
||||
cv::AutoBuffer<typename FlipVlen::TableElemType> buf(vl);
|
||||
// max vlen supported is 1024 (vlmax of u8m4 for vlen 1024 is 512)
|
||||
typename TabType::ElemType buf[512];
|
||||
flipFillBuffer(buf, vl, esz);
|
||||
tab_v = FlipVlen::loadTable(buf.data(), vl);
|
||||
tab_v = TabType::vload(buf, vl);
|
||||
}
|
||||
auto src0 = src_data, src1 = src_data + src_step * (src_height - 1);
|
||||
auto dst0 = dst_data, dst1 = dst_data + dst_step * (src_height - 1);
|
||||
|
||||
Vendored
+381
@@ -0,0 +1,381 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level
|
||||
// directory of this distribution and at http://opencv.org/license.html.
|
||||
#pragma once
|
||||
|
||||
#include <riscv_vector.h>
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
#undef cv_hal_log32f
|
||||
#define cv_hal_log32f cv::cv_hal_rvv::log32f
|
||||
#undef cv_hal_log64f
|
||||
#define cv_hal_log64f cv::cv_hal_rvv::log64f
|
||||
|
||||
namespace detail {
|
||||
|
||||
static constexpr size_t log_scale = 8;
|
||||
static constexpr size_t log_tab_size = ((size_t)1 << log_scale) * 2;
|
||||
static constexpr size_t log_mask = log_tab_size - 2;
|
||||
|
||||
static constexpr double ln_2 = 0.69314718055994530941723212145818;
|
||||
|
||||
static constexpr size_t log32f_mask = ((size_t)1 << (23 - log_scale)) - 1;
|
||||
static constexpr double log32f_a0 = 0.3333333333333333333333333f;
|
||||
static constexpr double log32f_a1 = -0.5f;
|
||||
static constexpr double log32f_a2 = 1.f;
|
||||
|
||||
static constexpr size_t log64f_mask = ((size_t)1 << (52 - log_scale)) - 1;
|
||||
static constexpr double log64f_a0 = -0.125;
|
||||
static constexpr double log64f_a1 = 0.1428571428571428769682682968777953647077083587646484375;
|
||||
static constexpr double log64f_a2 = -0.1666666666666666574148081281236954964697360992431640625;
|
||||
static constexpr double log64f_a3 = 0.2;
|
||||
static constexpr double log64f_a4 = -0.25;
|
||||
static constexpr double log64f_a5 = 0.333333333333333314829616256247390992939472198486328125;
|
||||
static constexpr double log64f_a6 = -0.5;
|
||||
static constexpr double log64f_a7 = 1.0;
|
||||
|
||||
#define LOG_TAB_VALUE \
|
||||
{ \
|
||||
0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000, \
|
||||
.00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420, \
|
||||
.00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760, \
|
||||
.01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884, \
|
||||
.01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846, \
|
||||
.01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877, \
|
||||
.02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084, \
|
||||
.02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498, \
|
||||
.03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697, \
|
||||
.03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906, \
|
||||
.03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624, \
|
||||
.04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509, \
|
||||
.04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239, \
|
||||
.04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234, \
|
||||
.05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481, \
|
||||
.05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465, \
|
||||
.06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647, \
|
||||
.06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377, \
|
||||
.06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657, \
|
||||
.07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909, \
|
||||
.07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971, \
|
||||
.07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856, \
|
||||
.08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201, \
|
||||
.08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240, \
|
||||
.08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143, \
|
||||
.09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470, \
|
||||
.09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035, \
|
||||
.10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484, \
|
||||
.10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141, \
|
||||
.10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982, \
|
||||
.11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951, \
|
||||
.11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627, \
|
||||
.11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889, \
|
||||
.12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962, \
|
||||
.12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690, \
|
||||
.12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024, \
|
||||
.13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233, \
|
||||
.13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031, \
|
||||
.13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422, \
|
||||
.14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983, \
|
||||
.14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649, \
|
||||
.14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620, \
|
||||
.15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201, \
|
||||
.15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127, \
|
||||
.15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333, \
|
||||
.16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365, \
|
||||
.16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536, \
|
||||
.16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449, \
|
||||
.17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421, \
|
||||
.17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377, \
|
||||
.17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131, \
|
||||
.18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440, \
|
||||
.18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312, \
|
||||
.18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479, \
|
||||
.19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516, \
|
||||
.19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087, \
|
||||
.19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205, \
|
||||
.20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441, \
|
||||
.20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032, \
|
||||
.20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127, \
|
||||
.21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848, \
|
||||
.21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817, \
|
||||
.21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088, \
|
||||
.22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991, \
|
||||
.22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000, \
|
||||
.22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611, \
|
||||
.22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689, \
|
||||
.23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808, \
|
||||
.23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901, \
|
||||
.23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077, \
|
||||
.24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387, \
|
||||
.24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544, \
|
||||
.24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049, \
|
||||
.25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888, \
|
||||
.25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758, \
|
||||
.25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106, \
|
||||
.25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819, \
|
||||
.26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688, \
|
||||
.26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491, \
|
||||
.26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791, \
|
||||
.27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619, \
|
||||
.27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196, \
|
||||
.27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112, \
|
||||
.28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985, \
|
||||
.28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118, \
|
||||
.28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378, \
|
||||
.28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485, \
|
||||
.29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504, \
|
||||
.29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070, \
|
||||
.29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377, \
|
||||
.30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746, \
|
||||
.30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308, \
|
||||
.30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908, \
|
||||
.30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908, \
|
||||
.31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714, \
|
||||
.31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293, \
|
||||
.31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273, \
|
||||
.32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246, \
|
||||
.32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486, \
|
||||
.32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113, \
|
||||
.32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382, \
|
||||
.33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112, \
|
||||
.33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095, \
|
||||
.33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412, \
|
||||
.34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111, \
|
||||
.34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197, \
|
||||
.34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017, \
|
||||
.34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325, \
|
||||
.35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033, \
|
||||
.35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986, \
|
||||
.35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814, \
|
||||
.36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978, \
|
||||
.36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478, \
|
||||
.36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377, \
|
||||
.36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919, \
|
||||
.37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504, \
|
||||
.37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430, \
|
||||
.37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158, \
|
||||
.37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198, \
|
||||
.38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667, \
|
||||
.38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277, \
|
||||
.38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377, \
|
||||
.38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772, \
|
||||
.39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686, \
|
||||
.39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737, \
|
||||
.39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026, \
|
||||
.40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084, \
|
||||
.40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230, \
|
||||
.40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667, \
|
||||
.40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649, \
|
||||
.41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544, \
|
||||
.41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173, \
|
||||
.41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268, \
|
||||
.41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298, \
|
||||
.42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564, \
|
||||
.42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450, \
|
||||
.42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816, \
|
||||
.42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056, \
|
||||
.43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162, \
|
||||
.43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278, \
|
||||
.43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465, \
|
||||
.43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305, \
|
||||
.44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794, \
|
||||
.44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416, \
|
||||
.44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000, \
|
||||
.44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805, \
|
||||
.45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159, \
|
||||
.45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320, \
|
||||
.45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337, \
|
||||
.45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321, \
|
||||
.46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064, \
|
||||
.46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290, \
|
||||
.46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098, \
|
||||
.46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511, \
|
||||
.47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439, \
|
||||
.47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105, \
|
||||
.47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359, \
|
||||
.47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131, \
|
||||
.48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314, \
|
||||
.48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855, \
|
||||
.48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154, \
|
||||
.48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801, \
|
||||
.49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124, \
|
||||
.49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487, \
|
||||
.49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095, \
|
||||
.49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420, \
|
||||
.49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711, \
|
||||
.50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690, \
|
||||
.50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566, \
|
||||
.50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294, \
|
||||
.50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094, \
|
||||
.51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126, \
|
||||
.51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458, \
|
||||
.51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967, \
|
||||
.51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256, \
|
||||
.52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705, \
|
||||
.52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926, \
|
||||
.52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617, \
|
||||
.52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512, \
|
||||
.53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126, \
|
||||
.53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908, \
|
||||
.53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771, \
|
||||
.53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489, \
|
||||
.53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695, \
|
||||
.54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818, \
|
||||
.54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948, \
|
||||
.54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321, \
|
||||
.54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084, \
|
||||
.55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766, \
|
||||
.55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506, \
|
||||
.55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960, \
|
||||
.55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801, \
|
||||
.55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714, \
|
||||
.56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590, \
|
||||
.56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889, \
|
||||
.56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945, \
|
||||
.56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239, \
|
||||
.57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691, \
|
||||
.57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502, \
|
||||
.57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626, \
|
||||
.57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614, \
|
||||
.57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094, \
|
||||
.58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310, \
|
||||
.58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754, \
|
||||
.58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783, \
|
||||
.58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397, \
|
||||
.59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541, \
|
||||
.59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395, \
|
||||
.59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931, \
|
||||
.59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344, \
|
||||
.59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811, \
|
||||
.60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338, \
|
||||
.60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470, \
|
||||
.60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279, \
|
||||
.60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021, \
|
||||
.60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021, \
|
||||
.61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864, \
|
||||
.61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505, \
|
||||
.61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565, \
|
||||
.61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789, \
|
||||
.62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084, \
|
||||
.62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725, \
|
||||
.62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556, \
|
||||
.62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234, \
|
||||
.62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333, \
|
||||
.63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322, \
|
||||
.63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320, \
|
||||
.63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126, \
|
||||
.63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744, \
|
||||
.63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814, \
|
||||
.64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934, \
|
||||
.64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961, \
|
||||
.64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361, \
|
||||
.64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591, \
|
||||
.64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653, \
|
||||
.65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762, \
|
||||
.65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033, \
|
||||
.65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288, \
|
||||
.65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182, \
|
||||
.65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172, \
|
||||
.66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323, \
|
||||
.66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080, \
|
||||
.66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213, \
|
||||
.66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547, \
|
||||
.66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000, \
|
||||
.67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661, \
|
||||
.67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450, \
|
||||
.67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489, \
|
||||
.67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079, \
|
||||
.67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069, \
|
||||
.68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711, \
|
||||
.68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742, \
|
||||
.68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520, \
|
||||
.68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220, \
|
||||
.68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078, \
|
||||
.69314718055994530941723212145818, 5.0e-01, \
|
||||
}
|
||||
|
||||
static constexpr float log_tab_32f[log_tab_size] = LOG_TAB_VALUE;
|
||||
static constexpr double log_tab_64f[log_tab_size] = LOG_TAB_VALUE;
|
||||
|
||||
#undef LOG_TAB_VALUE
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline int log32f(const float* src, float* dst, int _len)
|
||||
{
|
||||
size_t vl = __riscv_vsetvlmax_e32m4();
|
||||
auto log_a2 = __riscv_vfmv_v_f_f32m4(detail::log32f_a2, vl);
|
||||
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m4(len);
|
||||
auto i0 = __riscv_vle32_v_i32m4((const int32_t*)src, vl);
|
||||
|
||||
auto buf_i = __riscv_vor(__riscv_vand(i0, detail::log32f_mask, vl), 127 << 23, vl);
|
||||
auto idx = __riscv_vreinterpret_u32m4(__riscv_vand(
|
||||
__riscv_vsra(i0, 23 - detail::log_scale - 1 - 2, vl),
|
||||
detail::log_mask << 2,
|
||||
vl));
|
||||
|
||||
auto tab_v = __riscv_vluxei32(detail::log_tab_32f, idx, vl);
|
||||
auto y0_i = __riscv_vsub(__riscv_vand(__riscv_vsra(i0, 23, vl), 0xff, vl), 127, vl);
|
||||
auto y0 = __riscv_vfmadd(__riscv_vfcvt_f_x_v_f32m4(y0_i, vl), detail::ln_2, tab_v, vl);
|
||||
|
||||
tab_v = __riscv_vluxei32(detail::log_tab_32f, __riscv_vadd(idx, 4, vl), vl);
|
||||
auto buf_f = __riscv_vreinterpret_f32m4(buf_i);
|
||||
auto x0 = __riscv_vfmul(__riscv_vfsub(buf_f, 1.f, vl), tab_v, vl);
|
||||
x0 = __riscv_vfsub_mu(__riscv_vmseq(idx, (uint32_t)510 * 4, vl), x0, x0, 1.f / 512, vl);
|
||||
|
||||
auto res = __riscv_vfadd(__riscv_vfmul(x0, detail::log32f_a0, vl), detail::log32f_a1, vl);
|
||||
res = __riscv_vfmadd(res, x0, log_a2, vl);
|
||||
res = __riscv_vfmadd(res, x0, y0, vl);
|
||||
|
||||
__riscv_vse32(dst, res, vl);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int log64f(const double* src, double* dst, int _len)
|
||||
{
|
||||
size_t vl = __riscv_vsetvlmax_e64m4();
|
||||
// all vector registers are used up, so not load more constants
|
||||
auto log_a5 = __riscv_vfmv_v_f_f64m4(detail::log64f_a5, vl);
|
||||
auto log_a6 = __riscv_vfmv_v_f_f64m4(detail::log64f_a6, vl);
|
||||
auto log_a7 = __riscv_vfmv_v_f_f64m4(detail::log64f_a7, vl);
|
||||
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e64m4(len);
|
||||
auto i0 = __riscv_vle64_v_i64m4((const int64_t*)src, vl);
|
||||
|
||||
auto buf_i = __riscv_vor(__riscv_vand(i0, detail::log64f_mask, vl), (size_t)1023 << 52, vl);
|
||||
auto idx = __riscv_vreinterpret_u64m4(__riscv_vand(
|
||||
__riscv_vsra(i0, 52 - detail::log_scale - 1 - 3, vl),
|
||||
detail::log_mask << 3,
|
||||
vl));
|
||||
|
||||
auto tab_v = __riscv_vluxei64(detail::log_tab_64f, idx, vl);
|
||||
auto y0_i = __riscv_vsub(__riscv_vand(__riscv_vsra(i0, 52, vl), 0x7ff, vl), 1023, vl);
|
||||
auto y0 = __riscv_vfmadd(__riscv_vfcvt_f_x_v_f64m4(y0_i, vl), detail::ln_2, tab_v, vl);
|
||||
|
||||
tab_v = __riscv_vluxei64(detail::log_tab_64f, __riscv_vadd(idx, 8, vl), vl);
|
||||
auto buf_f = __riscv_vreinterpret_f64m4(buf_i);
|
||||
auto x0 = __riscv_vfmul(__riscv_vfsub(buf_f, 1.0, vl), tab_v, vl);
|
||||
x0 = __riscv_vfsub_mu(__riscv_vmseq(idx, (uint64_t)510 * 8, vl), x0, x0, 1. / 512, vl);
|
||||
|
||||
auto res = __riscv_vfadd(__riscv_vfmul(x0, detail::log64f_a0, vl), detail::log64f_a1, vl);
|
||||
res = __riscv_vfadd(__riscv_vfmul(x0, res, vl), detail::log64f_a2, vl);
|
||||
res = __riscv_vfadd(__riscv_vfmul(x0, res, vl), detail::log64f_a3, vl);
|
||||
res = __riscv_vfadd(__riscv_vfmul(x0, res, vl), detail::log64f_a4, vl);
|
||||
res = __riscv_vfmadd(res, x0, log_a5, vl);
|
||||
res = __riscv_vfmadd(res, x0, log_a6, vl);
|
||||
res = __riscv_vfmadd(res, x0, log_a7, vl);
|
||||
res = __riscv_vfmadd(res, x0, y0, vl);
|
||||
|
||||
__riscv_vse64(dst, res, vl);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}} // namespace cv::cv_hal_rvv
|
||||
Vendored
+169
@@ -0,0 +1,169 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_LU_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_LU_HPP_INCLUDED
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <typeinfo>
|
||||
#include <riscv_vector.h>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv { namespace lu {
|
||||
|
||||
#undef cv_hal_LU32f
|
||||
#define cv_hal_LU32f cv::cv_hal_rvv::lu::LU<cv::cv_hal_rvv::RVV_F32M4>
|
||||
#undef cv_hal_LU64f
|
||||
#define cv_hal_LU64f cv::cv_hal_rvv::lu::LU<cv::cv_hal_rvv::RVV_F64M4>
|
||||
|
||||
// the algorithm is copied from core/src/matrix_decomp.cpp,
|
||||
// in the function template static int cv::LUImpl
|
||||
template<typename RVV_T, typename T = typename RVV_T::ElemType>
|
||||
inline int LU(T* src1, size_t src1_step, int m, T* src2, size_t src2_step, int n, int* info)
|
||||
{
|
||||
T eps;
|
||||
if( typeid(T) == typeid(float) )
|
||||
eps = FLT_EPSILON*10;
|
||||
else if( typeid(T) == typeid(double) )
|
||||
eps = DBL_EPSILON*100;
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int i, j, k, p = 1;
|
||||
src1_step /= sizeof(src1[0]);
|
||||
src2_step /= sizeof(src2[0]);
|
||||
|
||||
int vlmax = RVV_T::setvlmax(), vl;
|
||||
if( src2 )
|
||||
{
|
||||
for( i = 0; i < m; i++ )
|
||||
{
|
||||
k = i;
|
||||
|
||||
for( j = i+1; j < m; j++ )
|
||||
if( std::abs(src1[j*src1_step + i]) > std::abs(src1[k*src1_step + i]) )
|
||||
k = j;
|
||||
|
||||
if( std::abs(src1[k*src1_step + i]) < eps )
|
||||
{
|
||||
*info = 0;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
if( k != i )
|
||||
{
|
||||
for( j = i; j < m; j += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - j);
|
||||
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + j, vl);
|
||||
auto vec_src2 = RVV_T::vload(src1 + k * src1_step + j, vl);
|
||||
RVV_T::vstore(src1 + k * src1_step + j, vec_src1, vl);
|
||||
RVV_T::vstore(src1 + i * src1_step + j, vec_src2, vl);
|
||||
}
|
||||
for( j = 0; j < n; j += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(n - j);
|
||||
auto vec_src1 = RVV_T::vload(src2 + i * src2_step + j, vl);
|
||||
auto vec_src2 = RVV_T::vload(src2 + k * src2_step + j, vl);
|
||||
RVV_T::vstore(src2 + k * src2_step + j, vec_src1, vl);
|
||||
RVV_T::vstore(src2 + i * src2_step + j, vec_src2, vl);
|
||||
}
|
||||
p = -p;
|
||||
}
|
||||
|
||||
T d = -1/src1[i*src1_step + i];
|
||||
|
||||
for( j = i+1; j < m; j++ )
|
||||
{
|
||||
T alpha = src1[j*src1_step + i]*d;
|
||||
|
||||
for( k = i+1; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src = RVV_T::vload(src1 + i * src1_step + k, vl);
|
||||
auto vec_dst = RVV_T::vload(src1 + j * src1_step + k, vl);
|
||||
vec_dst = __riscv_vfmacc(vec_dst, alpha, vec_src, vl);
|
||||
RVV_T::vstore(src1 + j * src1_step + k, vec_dst, vl);
|
||||
}
|
||||
for( k = 0; k < n; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(n - k);
|
||||
auto vec_src = RVV_T::vload(src2 + i * src2_step + k, vl);
|
||||
auto vec_dst = RVV_T::vload(src2 + j * src2_step + k, vl);
|
||||
vec_dst = __riscv_vfmacc(vec_dst, alpha, vec_src, vl);
|
||||
RVV_T::vstore(src2 + j * src2_step + k, vec_dst, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = m-1; i >= 0; i-- )
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
T s = src2[i*src2_step + j];
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = i+1; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + k, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src2 + k * src2_step + j, sizeof(T) * src2_step, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
s -= __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
src2[i*src2_step + j] = s/src1[i*src1_step + i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < m; i++ )
|
||||
{
|
||||
k = i;
|
||||
|
||||
for( j = i+1; j < m; j++ )
|
||||
if( std::abs(src1[j*src1_step + i]) > std::abs(src1[k*src1_step + i]) )
|
||||
k = j;
|
||||
|
||||
if( std::abs(src1[k*src1_step + i]) < eps )
|
||||
{
|
||||
*info = 0;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
if( k != i )
|
||||
{
|
||||
for( j = i; j < m; j += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - j);
|
||||
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + j, vl);
|
||||
auto vec_src2 = RVV_T::vload(src1 + k * src1_step + j, vl);
|
||||
RVV_T::vstore(src1 + k * src1_step + j, vec_src1, vl);
|
||||
RVV_T::vstore(src1 + i * src1_step + j, vec_src2, vl);
|
||||
}
|
||||
p = -p;
|
||||
}
|
||||
|
||||
T d = -1/src1[i*src1_step + i];
|
||||
|
||||
for( j = i+1; j < m; j++ )
|
||||
{
|
||||
T alpha = src1[j*src1_step + i]*d;
|
||||
|
||||
for( k = i+1; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src = RVV_T::vload(src1 + i * src1_step + k, vl);
|
||||
auto vec_dst = RVV_T::vload(src1 + j * src1_step + k, vl);
|
||||
vec_dst = __riscv_vfmacc(vec_dst, alpha, vec_src, vl);
|
||||
RVV_T::vstore(src1 + j * src1_step + k, vec_dst, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*info = p;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Vendored
+190
@@ -0,0 +1,190 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#pragma once
|
||||
|
||||
#include <riscv_vector.h>
|
||||
#include <opencv2/core/base.hpp>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
#undef cv_hal_lut
|
||||
#define cv_hal_lut cv::cv_hal_rvv::lut
|
||||
|
||||
// need vlen >= 256
|
||||
struct LUTCacheU8 : RVV_U8M8
|
||||
{
|
||||
using TabType = RVV_U8M8;
|
||||
using SrcType = RVV_SameLen<uint8_t, TabType>;
|
||||
using IdxType = RVV_SameLen<uint8_t, TabType>;
|
||||
|
||||
using ElemType = typename TabType::ElemType;
|
||||
constexpr static size_t elem_size = sizeof(ElemType);
|
||||
|
||||
static inline typename TabType::VecType
|
||||
gather(typename IdxType::VecType src_v, typename TabType::VecType lut_v, size_t vl)
|
||||
{
|
||||
return __riscv_vrgather(lut_v, src_v, vl);
|
||||
}
|
||||
};
|
||||
|
||||
// need vlen >= 512
|
||||
struct LUTCacheU16 : RVV_U16M8
|
||||
{
|
||||
using TabType = RVV_U16M8;
|
||||
using SrcType = RVV_SameLen<uint8_t, TabType>;
|
||||
using IdxType = RVV_SameLen<uint16_t, TabType>;
|
||||
|
||||
using ElemType = typename TabType::ElemType;
|
||||
constexpr static size_t elem_size = sizeof(ElemType);
|
||||
|
||||
static inline typename TabType::VecType
|
||||
gather(typename IdxType::VecType src_v, typename TabType::VecType lut_v, size_t vl)
|
||||
{
|
||||
return __riscv_vrgather(lut_v, src_v, vl);
|
||||
}
|
||||
};
|
||||
|
||||
// need vlen >= 1024
|
||||
struct LUTCacheU32 : RVV_U32M8
|
||||
{
|
||||
using TabType = RVV_U32M8;
|
||||
using SrcType = RVV_SameLen<uint8_t, TabType>;
|
||||
using IdxType = RVV_SameLen<uint16_t, TabType>;
|
||||
|
||||
using ElemType = typename TabType::ElemType;
|
||||
constexpr static size_t elem_size = sizeof(ElemType);
|
||||
|
||||
static inline typename TabType::VecType
|
||||
gather(typename IdxType::VecType src_v, typename TabType::VecType lut_v, size_t vl)
|
||||
{
|
||||
return __riscv_vrgatherei16(lut_v, src_v, vl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename LUT_TYPE>
|
||||
class LUTParallelBody : public cv::ParallelLoopBody
|
||||
{
|
||||
using ElemType = typename LUT_TYPE::ElemType;
|
||||
|
||||
public:
|
||||
const uchar* src_data;
|
||||
const uchar* lut_data;
|
||||
uchar* dst_data;
|
||||
size_t src_step;
|
||||
size_t dst_step;
|
||||
size_t width;
|
||||
|
||||
LUTParallelBody(const uchar* src_data,
|
||||
size_t src_step,
|
||||
const uchar* lut_data,
|
||||
uchar* dst_data,
|
||||
size_t dst_step,
|
||||
size_t width) :
|
||||
src_data(src_data), lut_data(lut_data), dst_data(dst_data), src_step(src_step),
|
||||
dst_step(dst_step), width(width)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const cv::Range& range) const CV_OVERRIDE
|
||||
{
|
||||
auto src = src_data + range.start * src_step;
|
||||
auto dst = dst_data + range.start * dst_step;
|
||||
size_t h = range.size();
|
||||
size_t w = width;
|
||||
if (w == src_step && w * LUT_TYPE::elem_size == dst_step)
|
||||
{
|
||||
w = w * h;
|
||||
h = 1;
|
||||
}
|
||||
auto lut = LUT_TYPE::vload((ElemType*)lut_data, 256);
|
||||
size_t maxlv = LUT_TYPE::setvlmax();
|
||||
for (; h; h--, src += src_step, dst += dst_step)
|
||||
{
|
||||
size_t vl = maxlv;
|
||||
size_t l = w;
|
||||
auto s = src;
|
||||
auto d = (ElemType*)dst;
|
||||
for (; l >= vl; l -= vl, s += vl, d += vl)
|
||||
{
|
||||
auto src_v = LUT_TYPE::SrcType::vload(s, vl);
|
||||
auto idx_v = LUT_TYPE::IdxType::cast(src_v, vl);
|
||||
auto dst_v = LUT_TYPE::gather(idx_v, lut, vl);
|
||||
LUT_TYPE::vstore(d, dst_v, vl);
|
||||
}
|
||||
for (; l > 0; l -= vl, s += vl, d += vl)
|
||||
{
|
||||
vl = LUT_TYPE::setvl(l);
|
||||
auto src_v = LUT_TYPE::SrcType::vload(s, vl);
|
||||
auto idx_v = LUT_TYPE::IdxType::cast(src_v, vl);
|
||||
auto dst_v = LUT_TYPE::gather(idx_v, lut, vl);
|
||||
LUT_TYPE::vstore(d, dst_v, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
LUTParallelBody(const LUTParallelBody&);
|
||||
LUTParallelBody& operator=(const LUTParallelBody&);
|
||||
};
|
||||
|
||||
inline int lut(const uchar* src_data,
|
||||
size_t src_step,
|
||||
size_t src_type,
|
||||
const uchar* lut_data,
|
||||
size_t lut_channel_size,
|
||||
size_t lut_channels,
|
||||
uchar* dst_data,
|
||||
size_t dst_step,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
size_t w = width;
|
||||
size_t h = height;
|
||||
size_t vlen = __riscv_vsetvlmax_e8m8();
|
||||
if (lut_channels == 1)
|
||||
{
|
||||
w *= CV_MAT_CN(src_type);
|
||||
|
||||
// Actually, vlen 128 can use four u8m4 vectors to load the whole table, gather and merge
|
||||
// the result, but the performance is almost the same as the scalar.
|
||||
if (lut_channel_size == 1 && vlen >= 256)
|
||||
{
|
||||
LUTParallelBody<LUTCacheU8> body(src_data, src_step, lut_data, dst_data, dst_step, w);
|
||||
Range all(0, height);
|
||||
if (w * h >= (1 << 18))
|
||||
cv::parallel_for_(all, body);
|
||||
else
|
||||
body(all);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if (lut_channel_size == 2 && vlen >= 512)
|
||||
{
|
||||
LUTParallelBody<LUTCacheU16> body(src_data, src_step, lut_data, dst_data, dst_step, w);
|
||||
Range all(0, height);
|
||||
if (w * h >= (1 << 18))
|
||||
cv::parallel_for_(all, body);
|
||||
else
|
||||
body(all);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if (lut_channel_size == 4 && vlen >= 1024)
|
||||
{
|
||||
LUTParallelBody<LUTCacheU32> body(src_data, src_step, lut_data, dst_data, dst_step, w);
|
||||
Range all(0, height);
|
||||
if (w * h >= (1 << 18))
|
||||
cv::parallel_for_(all, body);
|
||||
else
|
||||
body(all);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
}} // namespace cv::cv_hal_rvv
|
||||
+60
-109
@@ -1,76 +1,27 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_MINMAXIDX_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_MINMAXIDX_HPP_INCLUDED
|
||||
#ifndef OPENCV_HAL_RVV_MINMAX_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_MINMAX_HPP_INCLUDED
|
||||
|
||||
#include <riscv_vector.h>
|
||||
#include <opencv2/core/base.hpp>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
namespace cv { namespace cv_hal_rvv { namespace minmax {
|
||||
|
||||
#undef cv_hal_minMaxIdx
|
||||
#define cv_hal_minMaxIdx cv::cv_hal_rvv::minMaxIdx
|
||||
#define cv_hal_minMaxIdx cv::cv_hal_rvv::minmax::minMaxIdx
|
||||
#undef cv_hal_minMaxIdxMaskStep
|
||||
#define cv_hal_minMaxIdxMaskStep cv::cv_hal_rvv::minMaxIdx
|
||||
#define cv_hal_minMaxIdxMaskStep cv::cv_hal_rvv::minmax::minMaxIdx
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T> struct rvv;
|
||||
|
||||
#define HAL_RVV_GENERATOR(T, EEW, TYPE, IS_U, EMUL, M_EMUL, B_LEN) \
|
||||
template<> struct rvv<T> \
|
||||
{ \
|
||||
using vec_t = v##IS_U##int##EEW##EMUL##_t; \
|
||||
using bool_t = vbool##B_LEN##_t; \
|
||||
static inline size_t vsetvlmax() { return __riscv_vsetvlmax_e##EEW##EMUL(); } \
|
||||
static inline size_t vsetvl(size_t a) { return __riscv_vsetvl_e##EEW##EMUL(a); } \
|
||||
static inline vec_t vmv_v_x(T a, size_t b) { return __riscv_vmv_v_x_##TYPE##EMUL(a, b); } \
|
||||
static inline vec_t vle(const T* a, size_t b) { return __riscv_vle##EEW##_v_##TYPE##EMUL(a, b); } \
|
||||
static inline vuint8##M_EMUL##_t vle_mask(const uchar* a, size_t b) { return __riscv_vle8_v_u8##M_EMUL(a, b); } \
|
||||
static inline vec_t vmin_tu(vec_t a, vec_t b, vec_t c, size_t d) { return __riscv_vmin##IS_U##_tu(a, b, c, d); } \
|
||||
static inline vec_t vmax_tu(vec_t a, vec_t b, vec_t c, size_t d) { return __riscv_vmax##IS_U##_tu(a, b, c, d); } \
|
||||
static inline vec_t vmin_tumu(bool_t a, vec_t b, vec_t c, vec_t d, size_t e) { return __riscv_vmin##IS_U##_tumu(a, b, c, d, e); } \
|
||||
static inline vec_t vmax_tumu(bool_t a, vec_t b, vec_t c, vec_t d, size_t e) { return __riscv_vmax##IS_U##_tumu(a, b, c, d, e); } \
|
||||
static inline vec_t vredmin(vec_t a, vec_t b, size_t c) { return __riscv_vredmin##IS_U(a, b, c); } \
|
||||
static inline vec_t vredmax(vec_t a, vec_t b, size_t c) { return __riscv_vredmax##IS_U(a, b, c); } \
|
||||
};
|
||||
HAL_RVV_GENERATOR(uchar , 8 , u8 , u, m1, m1 , 8 )
|
||||
HAL_RVV_GENERATOR(schar , 8 , i8 , , m1, m1 , 8 )
|
||||
HAL_RVV_GENERATOR(ushort, 16, u16, u, m1, mf2, 16)
|
||||
HAL_RVV_GENERATOR(short , 16, i16, , m1, mf2, 16)
|
||||
#undef HAL_RVV_GENERATOR
|
||||
|
||||
#define HAL_RVV_GENERATOR(T, NAME, EEW, TYPE, IS_F, F_OR_S, F_OR_X, EMUL, M_EMUL, P_EMUL, B_LEN) \
|
||||
template<> struct rvv<T> \
|
||||
{ \
|
||||
using vec_t = v##NAME##EEW##EMUL##_t; \
|
||||
using bool_t = vbool##B_LEN##_t; \
|
||||
static inline size_t vsetvlmax() { return __riscv_vsetvlmax_e##EEW##EMUL(); } \
|
||||
static inline size_t vsetvl(size_t a) { return __riscv_vsetvl_e##EEW##EMUL(a); } \
|
||||
static inline vec_t vmv_v_x(T a, size_t b) { return __riscv_v##IS_F##mv_v_##F_OR_X##_##TYPE##EMUL(a, b); } \
|
||||
static inline vuint32##P_EMUL##_t vid(size_t a) { return __riscv_vid_v_u32##P_EMUL(a); } \
|
||||
static inline vuint32##P_EMUL##_t vundefined() { return __riscv_vundefined_u32##P_EMUL(); } \
|
||||
static inline vec_t vle(const T* a, size_t b) { return __riscv_vle##EEW##_v_##TYPE##EMUL(a, b); } \
|
||||
static inline vuint8##M_EMUL##_t vle_mask(const uchar* a, size_t b) { return __riscv_vle8_v_u8##M_EMUL(a, b); } \
|
||||
static inline bool_t vmlt(vec_t a, vec_t b, size_t c) { return __riscv_vm##F_OR_S##lt(a, b, c); } \
|
||||
static inline bool_t vmgt(vec_t a, vec_t b, size_t c) { return __riscv_vm##F_OR_S##gt(a, b, c); } \
|
||||
static inline bool_t vmlt_mu(bool_t a, bool_t b, vec_t c, vec_t d, size_t e) { return __riscv_vm##F_OR_S##lt##_mu(a, b, c, d, e); } \
|
||||
static inline bool_t vmgt_mu(bool_t a, bool_t b, vec_t c, vec_t d, size_t e) { return __riscv_vm##F_OR_S##gt##_mu(a, b, c, d, e); } \
|
||||
static inline T vmv_x_s(vec_t a) { return __riscv_v##IS_F##mv_##F_OR_X(a); } \
|
||||
};
|
||||
HAL_RVV_GENERATOR(int , int , 32, i32, , s, x, m4, m1 , m4, 8 )
|
||||
HAL_RVV_GENERATOR(float , float, 32, f32, f, f, f, m4, m1 , m4, 8 )
|
||||
HAL_RVV_GENERATOR(double, float, 64, f64, f, f, f, m4, mf2, m2, 16)
|
||||
#undef HAL_RVV_GENERATOR
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename VEC_T, typename BOOL_T, typename T = typename VEC_T::ElemType>
|
||||
inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width, int height, double* minVal, double* maxVal,
|
||||
int* minIdx, int* maxIdx, uchar* mask, size_t mask_step)
|
||||
{
|
||||
int vlmax = rvv<T>::vsetvlmax();
|
||||
auto vec_min = rvv<T>::vmv_v_x(std::numeric_limits<T>::max(), vlmax);
|
||||
auto vec_max = rvv<T>::vmv_v_x(std::numeric_limits<T>::lowest(), vlmax);
|
||||
int vlmax = VEC_T::setvlmax();
|
||||
auto vec_min = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
|
||||
auto vec_max = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
|
||||
T val_min, val_max;
|
||||
|
||||
if (mask)
|
||||
@@ -82,19 +33,19 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width,
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = rvv<T>::vsetvl(width - j);
|
||||
auto vec_src = rvv<T>::vle(src_row + j, vl);
|
||||
auto vec_mask = rvv<T>::vle_mask(mask_row + j, vl);
|
||||
vl = VEC_T::setvl(width - j);
|
||||
auto vec_src = VEC_T::vload(src_row + j, vl);
|
||||
auto vec_mask = BOOL_T::vload(mask_row + j, vl);
|
||||
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
|
||||
vec_min = rvv<T>::vmin_tumu(bool_mask, vec_min, vec_min, vec_src, vl);
|
||||
vec_max = rvv<T>::vmax_tumu(bool_mask, vec_max, vec_max, vec_src, vl);
|
||||
vec_min = VEC_T::vmin_tumu(bool_mask, vec_min, vec_min, vec_src, vl);
|
||||
vec_max = VEC_T::vmax_tumu(bool_mask, vec_max, vec_max, vec_src, vl);
|
||||
}
|
||||
}
|
||||
|
||||
auto sc_minval = rvv<T>::vmv_v_x(std::numeric_limits<T>::max(), vlmax);
|
||||
auto sc_maxval = rvv<T>::vmv_v_x(std::numeric_limits<T>::lowest(), vlmax);
|
||||
sc_minval = rvv<T>::vredmin(vec_min, sc_minval, vlmax);
|
||||
sc_maxval = rvv<T>::vredmax(vec_max, sc_maxval, vlmax);
|
||||
auto sc_minval = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
|
||||
auto sc_maxval = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
|
||||
sc_minval = VEC_T::vredmin(vec_min, sc_minval, vlmax);
|
||||
sc_maxval = VEC_T::vredmax(vec_max, sc_maxval, vlmax);
|
||||
val_min = __riscv_vmv_x(sc_minval);
|
||||
val_max = __riscv_vmv_x(sc_maxval);
|
||||
|
||||
@@ -106,9 +57,9 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width,
|
||||
int vl;
|
||||
for (int j = 0; j < width && (!found_min || !found_max); j += vl)
|
||||
{
|
||||
vl = rvv<T>::vsetvl(width - j);
|
||||
auto vec_src = rvv<T>::vle(src_row + j, vl);
|
||||
auto vec_mask = rvv<T>::vle_mask(mask_row + j, vl);
|
||||
vl = VEC_T::setvl(width - j);
|
||||
auto vec_src = VEC_T::vload(src_row + j, vl);
|
||||
auto vec_mask = BOOL_T::vload(mask_row + j, vl);
|
||||
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
|
||||
auto bool_zero = __riscv_vmxor(bool_mask, bool_mask, vl);
|
||||
if (!found_min)
|
||||
@@ -148,17 +99,17 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width,
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = rvv<T>::vsetvl(width - j);
|
||||
auto vec_src = rvv<T>::vle(src_row + j, vl);
|
||||
vec_min = rvv<T>::vmin_tu(vec_min, vec_min, vec_src, vl);
|
||||
vec_max = rvv<T>::vmax_tu(vec_max, vec_max, vec_src, vl);
|
||||
vl = VEC_T::setvl(width - j);
|
||||
auto vec_src = VEC_T::vload(src_row + j, vl);
|
||||
vec_min = VEC_T::vmin_tu(vec_min, vec_min, vec_src, vl);
|
||||
vec_max = VEC_T::vmax_tu(vec_max, vec_max, vec_src, vl);
|
||||
}
|
||||
}
|
||||
|
||||
auto sc_minval = rvv<T>::vmv_v_x(std::numeric_limits<T>::max(), vlmax);
|
||||
auto sc_maxval = rvv<T>::vmv_v_x(std::numeric_limits<T>::lowest(), vlmax);
|
||||
sc_minval = rvv<T>::vredmin(vec_min, sc_minval, vlmax);
|
||||
sc_maxval = rvv<T>::vredmax(vec_max, sc_maxval, vlmax);
|
||||
auto sc_minval = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
|
||||
auto sc_maxval = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
|
||||
sc_minval = VEC_T::vredmin(vec_min, sc_minval, vlmax);
|
||||
sc_maxval = VEC_T::vredmax(vec_max, sc_maxval, vlmax);
|
||||
val_min = __riscv_vmv_x(sc_minval);
|
||||
val_max = __riscv_vmv_x(sc_maxval);
|
||||
|
||||
@@ -169,8 +120,8 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width,
|
||||
int vl;
|
||||
for (int j = 0; j < width && (!found_min || !found_max); j += vl)
|
||||
{
|
||||
vl = rvv<T>::vsetvl(width - j);
|
||||
auto vec_src = rvv<T>::vle(src_row + j, vl);
|
||||
vl = VEC_T::setvl(width - j);
|
||||
auto vec_src = VEC_T::vload(src_row + j, vl);
|
||||
if (!found_min)
|
||||
{
|
||||
auto bool_minpos = __riscv_vmseq(vec_src, val_min, vl);
|
||||
@@ -212,15 +163,15 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width,
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename VEC_T, typename BOOL_T, typename IDX_T, typename T = typename VEC_T::ElemType>
|
||||
inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width, int height, double* minVal, double* maxVal,
|
||||
int* minIdx, int* maxIdx, uchar* mask, size_t mask_step)
|
||||
{
|
||||
int vlmax = rvv<T>::vsetvlmax();
|
||||
auto vec_min = rvv<T>::vmv_v_x(std::numeric_limits<T>::max(), vlmax);
|
||||
auto vec_max = rvv<T>::vmv_v_x(std::numeric_limits<T>::lowest(), vlmax);
|
||||
auto vec_pos = rvv<T>::vid(vlmax);
|
||||
auto vec_minpos = rvv<T>::vundefined(), vec_maxpos = rvv<T>::vundefined();
|
||||
int vlmax = VEC_T::setvlmax();
|
||||
auto vec_min = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
|
||||
auto vec_max = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
|
||||
auto vec_pos = IDX_T::vid(vlmax);
|
||||
auto vec_minpos = IDX_T::vundefined(), vec_maxpos = IDX_T::vundefined();
|
||||
T val_min, val_max;
|
||||
|
||||
if (mask)
|
||||
@@ -232,14 +183,14 @@ inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width,
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = rvv<T>::vsetvl(width - j);
|
||||
auto vec_src = rvv<T>::vle(src_row + j, vl);
|
||||
auto vec_mask = rvv<T>::vle_mask(mask_row + j, vl);
|
||||
vl = VEC_T::setvl(width - j);
|
||||
auto vec_src = VEC_T::vload(src_row + j, vl);
|
||||
auto vec_mask = BOOL_T::vload(mask_row + j, vl);
|
||||
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
|
||||
auto bool_zero = __riscv_vmxor(bool_mask, bool_mask, vl);
|
||||
|
||||
auto bool_minpos = rvv<T>::vmlt_mu(bool_mask, bool_zero, vec_src, vec_min, vl);
|
||||
auto bool_maxpos = rvv<T>::vmgt_mu(bool_mask, bool_zero, vec_src, vec_max, vl);
|
||||
auto bool_minpos = VEC_T::vmlt_mu(bool_mask, bool_zero, vec_src, vec_min, vl);
|
||||
auto bool_maxpos = VEC_T::vmgt_mu(bool_mask, bool_zero, vec_src, vec_max, vl);
|
||||
vec_minpos = __riscv_vmerge_tu(vec_minpos, vec_minpos, vec_pos, bool_minpos, vl);
|
||||
vec_maxpos = __riscv_vmerge_tu(vec_maxpos, vec_maxpos, vec_pos, bool_maxpos, vl);
|
||||
|
||||
@@ -257,11 +208,11 @@ inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width,
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = rvv<T>::vsetvl(width - j);
|
||||
auto vec_src = rvv<T>::vle(src_row + j, vl);
|
||||
vl = VEC_T::setvl(width - j);
|
||||
auto vec_src = VEC_T::vload(src_row + j, vl);
|
||||
|
||||
auto bool_minpos = rvv<T>::vmlt(vec_src, vec_min, vl);
|
||||
auto bool_maxpos = rvv<T>::vmgt(vec_src, vec_max, vl);
|
||||
auto bool_minpos = VEC_T::vmlt(vec_src, vec_min, vl);
|
||||
auto bool_maxpos = VEC_T::vmgt(vec_src, vec_max, vl);
|
||||
vec_minpos = __riscv_vmerge_tu(vec_minpos, vec_minpos, vec_pos, bool_minpos, vl);
|
||||
vec_maxpos = __riscv_vmerge_tu(vec_maxpos, vec_maxpos, vec_pos, bool_maxpos, vl);
|
||||
|
||||
@@ -276,9 +227,9 @@ inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width,
|
||||
val_max = std::numeric_limits<T>::lowest();
|
||||
for (int i = 0; i < vlmax; i++)
|
||||
{
|
||||
if (val_min > rvv<T>::vmv_x_s(vec_min))
|
||||
if (val_min > VEC_T::vmv_x(vec_min))
|
||||
{
|
||||
val_min = rvv<T>::vmv_x_s(vec_min);
|
||||
val_min = VEC_T::vmv_x(vec_min);
|
||||
if (minIdx)
|
||||
{
|
||||
minIdx[0] = __riscv_vmv_x(vec_minpos) / width;
|
||||
@@ -287,9 +238,9 @@ inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width,
|
||||
std::swap(minIdx[0], minIdx[1]);
|
||||
}
|
||||
}
|
||||
if (val_max < rvv<T>::vmv_x_s(vec_max))
|
||||
if (val_max < VEC_T::vmv_x(vec_max))
|
||||
{
|
||||
val_max = rvv<T>::vmv_x_s(vec_max);
|
||||
val_max = VEC_T::vmv_x(vec_max);
|
||||
if (maxIdx)
|
||||
{
|
||||
maxIdx[0] = __riscv_vmv_x(vec_maxpos) / width;
|
||||
@@ -324,24 +275,24 @@ inline int minMaxIdx(const uchar* src_data, size_t src_step, int width, int heig
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8UC1:
|
||||
return minMaxIdxReadTwice<uchar>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadTwice<RVV_U8M1, RVV_U8M1>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
case CV_8SC1:
|
||||
return minMaxIdxReadTwice<schar>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadTwice<RVV_I8M1, RVV_U8M1>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
case CV_16UC1:
|
||||
return minMaxIdxReadTwice<ushort>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadTwice<RVV_U16M1, RVV_U8MF2>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
case CV_16SC1:
|
||||
return minMaxIdxReadTwice<short>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadTwice<RVV_I16M1, RVV_U8MF2>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
case CV_32SC1:
|
||||
return minMaxIdxReadOnce<int>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadOnce<RVV_I32M4, RVV_U8M1, RVV_U32M4>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
case CV_32FC1:
|
||||
return minMaxIdxReadOnce<float>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadOnce<RVV_F32M4, RVV_U8M1, RVV_U32M4>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
case CV_64FC1:
|
||||
return minMaxIdxReadOnce<double>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
return minMaxIdxReadOnce<RVV_F64M4, RVV_U8MF2, RVV_U32M2>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
}}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -6,10 +6,10 @@
|
||||
|
||||
#include <riscv_vector.h>
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
namespace cv { namespace cv_hal_rvv { namespace norm {
|
||||
|
||||
#undef cv_hal_norm
|
||||
#define cv_hal_norm cv::cv_hal_rvv::norm
|
||||
#define cv_hal_norm cv::cv_hal_rvv::norm::norm
|
||||
|
||||
inline int normInf_8UC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
|
||||
{
|
||||
@@ -512,6 +512,6 @@ inline int norm(const uchar* src, size_t src_step, const uchar* mask, size_t mas
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
}}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+4
-4
@@ -6,10 +6,10 @@
|
||||
|
||||
#include <riscv_vector.h>
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
namespace cv { namespace cv_hal_rvv { namespace norm_diff {
|
||||
|
||||
#undef cv_hal_normDiff
|
||||
#define cv_hal_normDiff cv::cv_hal_rvv::normDiff
|
||||
#define cv_hal_normDiff cv::cv_hal_rvv::norm_diff::normDiff
|
||||
|
||||
inline int normDiffInf_8UC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
|
||||
{
|
||||
@@ -590,7 +590,7 @@ inline int normDiff(const uchar* src1, size_t src1_step, const uchar* src2, size
|
||||
if(ret == CV_HAL_ERROR_OK && (norm_type & NORM_RELATIVE))
|
||||
{
|
||||
double result_;
|
||||
ret = cv::cv_hal_rvv::norm(src2, src2_step, mask, mask_step, width, height, type, norm_type & ~NORM_RELATIVE, &result_);
|
||||
ret = cv::cv_hal_rvv::norm::norm(src2, src2_step, mask, mask_step, width, height, type, norm_type & ~NORM_RELATIVE, &result_);
|
||||
if(ret == CV_HAL_ERROR_OK)
|
||||
{
|
||||
*result /= result_ + DBL_EPSILON;
|
||||
@@ -600,6 +600,6 @@ inline int normDiff(const uchar* src1, size_t src1_step, const uchar* src2, size
|
||||
return ret;
|
||||
}
|
||||
|
||||
}}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+600
@@ -0,0 +1,600 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_PYRAMIDS_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_PYRAMIDS_HPP_INCLUDED
|
||||
|
||||
#include <riscv_vector.h>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv { namespace pyramids {
|
||||
|
||||
#undef cv_hal_pyrdown
|
||||
#define cv_hal_pyrdown cv::cv_hal_rvv::pyramids::pyrDown
|
||||
#undef cv_hal_pyrup
|
||||
#define cv_hal_pyrup cv::cv_hal_rvv::pyramids::pyrUp
|
||||
|
||||
template<typename T> struct rvv;
|
||||
|
||||
template<> struct rvv<uchar>
|
||||
{
|
||||
using T = RVV_U8M1;
|
||||
using WT = RVV_SameLen<int, T>;
|
||||
using MT = RVV_SameLen<uint, T>;
|
||||
|
||||
static inline WT::VecType vcvt_T_WT(T::VecType a, size_t b) { return WT::cast(MT::cast(a, b), b); }
|
||||
static inline T::VecType vcvt_WT_T(WT::VecType a, int b, size_t c) { return T::cast(MT::cast(__riscv_vsra(__riscv_vadd(a, 1 << (b - 1), c), b, c), c), c); }
|
||||
static inline WT::VecType down0(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
|
||||
return __riscv_vadd(__riscv_vadd(__riscv_vadd(vec_src0, vec_src4, vl), __riscv_vadd(vec_src2, vec_src2, vl), vl),
|
||||
__riscv_vsll(__riscv_vadd(__riscv_vadd(vec_src1, vec_src2, vl), vec_src3, vl), 2, vl), vl);
|
||||
}
|
||||
static inline WT::VecType down1(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
|
||||
return down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl);
|
||||
}
|
||||
static inline WT::VecType up00(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vadd(__riscv_vadd(vec_src0, vec_src2, vl), __riscv_vadd(__riscv_vsll(vec_src1, 2, vl), __riscv_vsll(vec_src1, 1, vl), vl), vl);
|
||||
}
|
||||
static inline WT::VecType up01(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vsll(__riscv_vadd(vec_src1, vec_src2, vl), 2, vl);
|
||||
}
|
||||
static inline WT::VecType up10(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return up00(vec_src0, vec_src1, vec_src2, vl);
|
||||
}
|
||||
static inline WT::VecType up11(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return up01(vec_src1, vec_src2, vl);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct rvv<short>
|
||||
{
|
||||
using T = RVV_I16M2;
|
||||
using WT = RVV_SameLen<int, T>;
|
||||
using MT = RVV_SameLen<uint, T>;
|
||||
|
||||
static inline WT::VecType vcvt_T_WT(T::VecType a, size_t b) { return WT::cast(a, b); }
|
||||
static inline T::VecType vcvt_WT_T(WT::VecType a, int b, size_t c) { return T::cast(__riscv_vsra(__riscv_vadd(a, 1 << (b - 1), c), b, c), c); }
|
||||
static inline WT::VecType down0(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
|
||||
return __riscv_vadd(__riscv_vadd(__riscv_vadd(vec_src0, vec_src4, vl), __riscv_vadd(vec_src2, vec_src2, vl), vl),
|
||||
__riscv_vsll(__riscv_vadd(__riscv_vadd(vec_src1, vec_src2, vl), vec_src3, vl), 2, vl), vl);
|
||||
}
|
||||
static inline WT::VecType down1(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
|
||||
return down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl);
|
||||
}
|
||||
static inline WT::VecType up00(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vadd(__riscv_vadd(vec_src0, vec_src2, vl), __riscv_vadd(__riscv_vsll(vec_src1, 2, vl), __riscv_vsll(vec_src1, 1, vl), vl), vl);
|
||||
}
|
||||
static inline WT::VecType up01(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vsll(__riscv_vadd(vec_src1, vec_src2, vl), 2, vl);
|
||||
}
|
||||
static inline WT::VecType up10(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return up00(vec_src0, vec_src1, vec_src2, vl);
|
||||
}
|
||||
static inline WT::VecType up11(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return up01(vec_src1, vec_src2, vl);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct rvv<float>
|
||||
{
|
||||
using T = RVV_F32M4;
|
||||
using WT = RVV_SameLen<float, T>;
|
||||
using MT = RVV_SameLen<uint, T>;
|
||||
|
||||
static inline WT::VecType vcvt_T_WT(T::VecType a, size_t b) { return WT::cast(a, b); }
|
||||
static inline T::VecType vcvt_WT_T(WT::VecType a, [[maybe_unused]] int b, size_t c) { return T::cast(a, c); }
|
||||
static inline WT::VecType down0(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
|
||||
return __riscv_vfmadd(vec_src2, 6, __riscv_vfmadd(__riscv_vfadd(vec_src1, vec_src3, vl), 4, __riscv_vfadd(vec_src0, vec_src4, vl), vl), vl);
|
||||
}
|
||||
static inline WT::VecType down1(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
|
||||
return __riscv_vfmul(down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), 1.f / 256.f, vl);
|
||||
}
|
||||
static inline WT::VecType up00(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vfadd(__riscv_vfmadd(vec_src1, 6, vec_src0, vl), vec_src2, vl);
|
||||
}
|
||||
static inline WT::VecType up01(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vfmul(__riscv_vfadd(vec_src1, vec_src2, vl), 4, vl);
|
||||
}
|
||||
static inline WT::VecType up10(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vfmul(__riscv_vfadd(__riscv_vfmadd(vec_src1, 6, vec_src0, vl), vec_src2, vl), 1.f / 64.f, vl);
|
||||
}
|
||||
static inline WT::VecType up11(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
|
||||
return __riscv_vfmul(__riscv_vfadd(vec_src1, vec_src2, vl), 1.f / 16.f, vl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RVV>
|
||||
struct pyrDownVec0
|
||||
{
|
||||
using T = typename RVV::T::ElemType;
|
||||
using WT = typename RVV::WT::ElemType;
|
||||
|
||||
void operator()(const T* src, WT* row, const uint* tabM, int start, int end)
|
||||
{
|
||||
int vl;
|
||||
switch (start)
|
||||
{
|
||||
case 1:
|
||||
for( int x = start; x < end; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end - x);
|
||||
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 - 2, 2 * sizeof(T), vl), vl);
|
||||
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 - 1, 2 * sizeof(T), vl), vl);
|
||||
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2, 2 * sizeof(T), vl), vl);
|
||||
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 + 1, 2 * sizeof(T), vl), vl);
|
||||
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 + 2, 2 * sizeof(T), vl), vl);
|
||||
__riscv_vse32(row + x, RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for( int x = start / 2; x < end / 2; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end / 2 - x);
|
||||
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 2, 4 * sizeof(T), vl), vl);
|
||||
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 2, 4 * sizeof(T), vl), vl);
|
||||
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 2, 4 * sizeof(T), vl), vl);
|
||||
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 2, 4 * sizeof(T), vl), vl);
|
||||
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 2, 4 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 2, 2 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 2 + 1, 4 * sizeof(T), vl), vl);
|
||||
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 2 + 1, 4 * sizeof(T), vl), vl);
|
||||
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 2 + 1, 4 * sizeof(T), vl), vl);
|
||||
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 2 + 1, 4 * sizeof(T), vl), vl);
|
||||
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 2 + 1, 4 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 2 + 1, 2 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for( int x = start / 3; x < end / 3; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end / 3 - x);
|
||||
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 3, 6 * sizeof(T), vl), vl);
|
||||
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 3, 6 * sizeof(T), vl), vl);
|
||||
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 3, 6 * sizeof(T), vl), vl);
|
||||
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 3, 6 * sizeof(T), vl), vl);
|
||||
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 3, 6 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 3, 3 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 3 + 1, 6 * sizeof(T), vl), vl);
|
||||
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 3 + 1, 6 * sizeof(T), vl), vl);
|
||||
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 3 + 1, 6 * sizeof(T), vl), vl);
|
||||
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 3 + 1, 6 * sizeof(T), vl), vl);
|
||||
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 3 + 1, 6 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 3 + 1, 3 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 3 + 2, 6 * sizeof(T), vl), vl);
|
||||
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 3 + 2, 6 * sizeof(T), vl), vl);
|
||||
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 3 + 2, 6 * sizeof(T), vl), vl);
|
||||
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 3 + 2, 6 * sizeof(T), vl), vl);
|
||||
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 3 + 2, 6 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 3 + 2, 3 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for( int x = start / 4; x < end / 4; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end / 4 - x);
|
||||
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4, 8 * sizeof(T), vl), vl);
|
||||
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4, 8 * sizeof(T), vl), vl);
|
||||
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4, 8 * sizeof(T), vl), vl);
|
||||
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4, 8 * sizeof(T), vl), vl);
|
||||
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4, 8 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 4, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4 + 1, 8 * sizeof(T), vl), vl);
|
||||
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4 + 1, 8 * sizeof(T), vl), vl);
|
||||
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4 + 1, 8 * sizeof(T), vl), vl);
|
||||
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4 + 1, 8 * sizeof(T), vl), vl);
|
||||
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4 + 1, 8 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 4 + 1, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4 + 2, 8 * sizeof(T), vl), vl);
|
||||
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4 + 2, 8 * sizeof(T), vl), vl);
|
||||
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4 + 2, 8 * sizeof(T), vl), vl);
|
||||
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4 + 2, 8 * sizeof(T), vl), vl);
|
||||
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4 + 2, 8 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 4 + 2, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4 + 3, 8 * sizeof(T), vl), vl);
|
||||
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4 + 3, 8 * sizeof(T), vl), vl);
|
||||
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4 + 3, 8 * sizeof(T), vl), vl);
|
||||
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4 + 3, 8 * sizeof(T), vl), vl);
|
||||
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4 + 3, 8 * sizeof(T), vl), vl);
|
||||
__riscv_vsse32(row + x * 4 + 3, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for( int x = start; x < end; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end - x);
|
||||
auto vec_tabM = RVV::MT::vload(tabM + x, vl);
|
||||
vec_tabM = __riscv_vmul(__riscv_vsub(vec_tabM, start * 2, vl), sizeof(T), vl);
|
||||
auto vec_src0 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
|
||||
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
|
||||
auto vec_src1 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
|
||||
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
|
||||
auto vec_src2 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
|
||||
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
|
||||
auto vec_src3 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
|
||||
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
|
||||
auto vec_src4 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
|
||||
__riscv_vse32(row + x, RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RVV>
|
||||
struct pyrDownVec1
|
||||
{
|
||||
using T = typename RVV::T::ElemType;
|
||||
using WT = typename RVV::WT::ElemType;
|
||||
|
||||
void operator()(WT* row0, WT* row1, WT* row2, WT* row3, WT* row4, T* dst, int end)
|
||||
{
|
||||
int vl;
|
||||
for( int x = 0 ; x < end; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end - x);
|
||||
auto vec_src0 = RVV::WT::vload(row0 + x, vl);
|
||||
auto vec_src1 = RVV::WT::vload(row1 + x, vl);
|
||||
auto vec_src2 = RVV::WT::vload(row2 + x, vl);
|
||||
auto vec_src3 = RVV::WT::vload(row3 + x, vl);
|
||||
auto vec_src4 = RVV::WT::vload(row4 + x, vl);
|
||||
RVV::T::vstore(dst + x, RVV::vcvt_WT_T(RVV::down1(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), 8, vl), vl);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RVV>
|
||||
struct pyrUpVec0
|
||||
{
|
||||
using T = typename RVV::T::ElemType;
|
||||
using WT = typename RVV::WT::ElemType;
|
||||
|
||||
void operator()(const T* src, WT* row, const uint* dtab, int start, int end)
|
||||
{
|
||||
int vl;
|
||||
for( int x = start; x < end; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end - x);
|
||||
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload(src + x - start, vl), vl);
|
||||
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload(src + x, vl), vl);
|
||||
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload(src + x + start, vl), vl);
|
||||
|
||||
auto vec_dtab = RVV::MT::vload(dtab + x, vl);
|
||||
vec_dtab = __riscv_vmul(vec_dtab, sizeof(WT), vl);
|
||||
__riscv_vsoxei32(row, vec_dtab, RVV::up00(vec_src0, vec_src1, vec_src2, vl), vl);
|
||||
__riscv_vsoxei32(row, __riscv_vadd(vec_dtab, start * sizeof(WT), vl), RVV::up01(vec_src1, vec_src2, vl), vl);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RVV>
|
||||
struct pyrUpVec1
|
||||
{
|
||||
using T = typename RVV::T::ElemType;
|
||||
using WT = typename RVV::WT::ElemType;
|
||||
|
||||
void operator()(WT* row0, WT* row1, WT* row2, T* dst0, T* dst1, int end)
|
||||
{
|
||||
int vl;
|
||||
if (dst0 != dst1)
|
||||
{
|
||||
for( int x = 0 ; x < end; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end - x);
|
||||
auto vec_src0 = RVV::WT::vload(row0 + x, vl);
|
||||
auto vec_src1 = RVV::WT::vload(row1 + x, vl);
|
||||
auto vec_src2 = RVV::WT::vload(row2 + x, vl);
|
||||
RVV::T::vstore(dst0 + x, RVV::vcvt_WT_T(RVV::up10(vec_src0, vec_src1, vec_src2, vl), 6, vl), vl);
|
||||
RVV::T::vstore(dst1 + x, RVV::vcvt_WT_T(RVV::up11(vec_src1, vec_src2, vl), 6, vl), vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int x = 0 ; x < end; x += vl )
|
||||
{
|
||||
vl = RVV::WT::setvl(end - x);
|
||||
auto vec_src0 = RVV::WT::vload(row0 + x, vl);
|
||||
auto vec_src1 = RVV::WT::vload(row1 + x, vl);
|
||||
auto vec_src2 = RVV::WT::vload(row2 + x, vl);
|
||||
RVV::T::vstore(dst0 + x, RVV::vcvt_WT_T(RVV::up10(vec_src0, vec_src1, vec_src2, vl), 6, vl), vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RVV>
|
||||
struct PyrDownInvoker : ParallelLoopBody
|
||||
{
|
||||
PyrDownInvoker(const uchar* _src_data, size_t _src_step, int _src_width, int _src_height, uchar* _dst_data, size_t _dst_step, int _dst_width, int _dst_height, int _cn, int _borderType, int* _tabR, int* _tabM, int* _tabL)
|
||||
{
|
||||
src_data = _src_data;
|
||||
src_step = _src_step;
|
||||
src_width = _src_width;
|
||||
src_height = _src_height;
|
||||
dst_data = _dst_data;
|
||||
dst_step = _dst_step;
|
||||
dst_width = _dst_width;
|
||||
dst_height = _dst_height;
|
||||
cn = _cn;
|
||||
borderType = _borderType;
|
||||
tabR = _tabR;
|
||||
tabM = _tabM;
|
||||
tabL = _tabL;
|
||||
}
|
||||
|
||||
void operator()(const Range& range) const CV_OVERRIDE;
|
||||
|
||||
const uchar* src_data;
|
||||
size_t src_step;
|
||||
int src_width;
|
||||
int src_height;
|
||||
uchar* dst_data;
|
||||
size_t dst_step;
|
||||
int dst_width;
|
||||
int dst_height;
|
||||
int cn;
|
||||
int borderType;
|
||||
int* tabR;
|
||||
int* tabM;
|
||||
int* tabL;
|
||||
};
|
||||
|
||||
static inline int borderInterpolate( int p, int len, int borderType )
|
||||
{
|
||||
if( (unsigned)p < (unsigned)len )
|
||||
;
|
||||
else if( borderType == BORDER_REPLICATE )
|
||||
p = p < 0 ? 0 : len - 1;
|
||||
else if( borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101 )
|
||||
{
|
||||
int delta = borderType == BORDER_REFLECT_101;
|
||||
if( len == 1 )
|
||||
return 0;
|
||||
do
|
||||
{
|
||||
if( p < 0 )
|
||||
p = -p - 1 + delta;
|
||||
else
|
||||
p = len - 1 - (p - len) - delta;
|
||||
}
|
||||
while( (unsigned)p >= (unsigned)len );
|
||||
}
|
||||
else if( borderType == BORDER_WRAP )
|
||||
{
|
||||
if( p < 0 )
|
||||
p -= ((p-len+1)/len)*len;
|
||||
if( p >= len )
|
||||
p %= len;
|
||||
}
|
||||
else if( borderType == BORDER_CONSTANT )
|
||||
p = -1;
|
||||
return p;
|
||||
}
|
||||
|
||||
// the algorithm is copied from imgproc/src/pyramids.cpp,
|
||||
// in the function template void cv::pyrDown_
|
||||
|
||||
template <typename RVV>
|
||||
inline int pyrDown(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int cn, int borderType)
|
||||
{
|
||||
const int PD_SZ = 5;
|
||||
|
||||
std::vector<int> _tabM(dst_width * cn), _tabL(cn * (PD_SZ + 2)), _tabR(cn * (PD_SZ + 2));
|
||||
int *tabM = _tabM.data(), *tabL = _tabL.data(), *tabR = _tabR.data();
|
||||
|
||||
if( src_width <= 0 || src_height <= 0 ||
|
||||
std::abs(dst_width*2 - src_width) > 2 ||
|
||||
std::abs(dst_height*2 - src_height) > 2 )
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
int width0 = std::min((src_width-PD_SZ/2-1)/2 + 1, dst_width);
|
||||
|
||||
for (int x = 0; x <= PD_SZ+1; x++)
|
||||
{
|
||||
int sx0 = borderInterpolate(x - PD_SZ/2, src_width, borderType)*cn;
|
||||
int sx1 = borderInterpolate(x + width0*2 - PD_SZ/2, src_width, borderType)*cn;
|
||||
for (int k = 0; k < cn; k++)
|
||||
{
|
||||
tabL[x*cn + k] = sx0 + k;
|
||||
tabR[x*cn + k] = sx1 + k;
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = 0; x < dst_width*cn; x++)
|
||||
tabM[x] = (x/cn)*2*cn + x % cn;
|
||||
|
||||
cv::parallel_for_(Range(0,dst_height), PyrDownInvoker<RVV>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, borderType, tabR, tabM, tabL), cv::getNumThreads());
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
template <typename RVV>
|
||||
void PyrDownInvoker<RVV>::operator()(const Range& range) const
|
||||
{
|
||||
using T = typename RVV::T::ElemType;
|
||||
using WT = typename RVV::WT::ElemType;
|
||||
const int PD_SZ = 5;
|
||||
|
||||
int bufstep = (dst_width*cn + 15) & -16;
|
||||
std::vector<WT> _buf(bufstep*PD_SZ + 16);
|
||||
WT* buf = (WT*)(((size_t)_buf.data() + 15) & -16);
|
||||
WT* rows[PD_SZ];
|
||||
|
||||
int sy0 = -PD_SZ/2, sy = range.start * 2 + sy0, width0 = std::min((src_width-PD_SZ/2-1)/2 + 1, dst_width);
|
||||
|
||||
int _dst_width = dst_width * cn;
|
||||
width0 *= cn;
|
||||
|
||||
for (int y = range.start; y < range.end; y++)
|
||||
{
|
||||
T* dst = reinterpret_cast<T*>(dst_data + dst_step * y);
|
||||
WT *row0, *row1, *row2, *row3, *row4;
|
||||
|
||||
// fill the ring buffer (horizontal convolution and decimation)
|
||||
int sy_limit = y*2 + 2;
|
||||
for( ; sy <= sy_limit; sy++ )
|
||||
{
|
||||
WT* row = buf + ((sy - sy0) % PD_SZ)*bufstep;
|
||||
int _sy = borderInterpolate(sy, src_height, borderType);
|
||||
const T* src = reinterpret_cast<const T*>(src_data + src_step * _sy);
|
||||
|
||||
do {
|
||||
int x = 0;
|
||||
for( ; x < cn; x++ )
|
||||
{
|
||||
row[x] = src[tabL[x+cn*2]]*6 + (src[tabL[x+cn]] + src[tabL[x+cn*3]])*4 +
|
||||
src[tabL[x]] + src[tabL[x+cn*4]];
|
||||
}
|
||||
|
||||
if( x == _dst_width )
|
||||
break;
|
||||
|
||||
pyrDownVec0<RVV>()(src, row, reinterpret_cast<const uint*>(tabM), cn, width0);
|
||||
x = width0;
|
||||
|
||||
// tabR
|
||||
for (int x_ = 0; x < _dst_width; x++, x_++)
|
||||
{
|
||||
row[x] = src[tabR[x_+cn*2]]*6 + (src[tabR[x_+cn]] + src[tabR[x_+cn*3]])*4 +
|
||||
src[tabR[x_]] + src[tabR[x_+cn*4]];
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
// do vertical convolution and decimation and write the result to the destination image
|
||||
for (int k = 0; k < PD_SZ; k++)
|
||||
rows[k] = buf + ((y*2 - PD_SZ/2 + k - sy0) % PD_SZ)*bufstep;
|
||||
row0 = rows[0]; row1 = rows[1]; row2 = rows[2]; row3 = rows[3]; row4 = rows[4];
|
||||
|
||||
pyrDownVec1<RVV>()(row0, row1, row2, row3, row4, dst, _dst_width);
|
||||
}
|
||||
}
|
||||
|
||||
// the algorithm is copied from imgproc/src/pyramids.cpp,
|
||||
// in the function template void cv::pyrUp_
|
||||
template <typename RVV>
|
||||
inline int pyrUp(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int cn)
|
||||
{
|
||||
using T = typename RVV::T::ElemType;
|
||||
using WT = typename RVV::WT::ElemType;
|
||||
const int PU_SZ = 3;
|
||||
|
||||
int bufstep = ((dst_width+1)*cn + 15) & -16;
|
||||
std::vector<WT> _buf(bufstep*PU_SZ + 16);
|
||||
WT* buf = (WT*)(((size_t)_buf.data() + 15) & -16);
|
||||
std::vector<int> _dtab(src_width*cn);
|
||||
int* dtab = _dtab.data();
|
||||
WT* rows[PU_SZ];
|
||||
|
||||
if( std::abs(dst_width - src_width*2) != dst_width % 2 ||
|
||||
std::abs(dst_height - src_height*2) != dst_height % 2)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
int k, x, sy0 = -PU_SZ/2, sy = sy0;
|
||||
|
||||
src_width *= cn;
|
||||
dst_width *= cn;
|
||||
|
||||
for( x = 0; x < src_width; x++ )
|
||||
dtab[x] = (x/cn)*2*cn + x % cn;
|
||||
|
||||
for( int y = 0; y < src_height; y++ )
|
||||
{
|
||||
T* dst0 = reinterpret_cast<T*>(dst_data + dst_step * (y*2));
|
||||
T* dst1 = reinterpret_cast<T*>(dst_data + dst_step * (std::min(y*2+1, dst_height-1)));
|
||||
WT *row0, *row1, *row2;
|
||||
|
||||
// fill the ring buffer (horizontal convolution and decimation)
|
||||
for( ; sy <= y + 1; sy++ )
|
||||
{
|
||||
WT* row = buf + ((sy - sy0) % PU_SZ)*bufstep;
|
||||
int _sy = borderInterpolate(sy*2, src_height*2, (int)BORDER_REFLECT_101)/2;
|
||||
const T* src = reinterpret_cast<const T*>(src_data + src_step * _sy);
|
||||
|
||||
if( src_width == cn )
|
||||
{
|
||||
for( x = 0; x < cn; x++ )
|
||||
row[x] = row[x + cn] = src[x]*8;
|
||||
continue;
|
||||
}
|
||||
|
||||
for( x = 0; x < cn; x++ )
|
||||
{
|
||||
int dx = dtab[x];
|
||||
WT t0 = src[x]*6 + src[x + cn]*2;
|
||||
WT t1 = (src[x] + src[x + cn])*4;
|
||||
row[dx] = t0; row[dx + cn] = t1;
|
||||
dx = dtab[src_width - cn + x];
|
||||
int sx = src_width - cn + x;
|
||||
t0 = src[sx - cn] + src[sx]*7;
|
||||
t1 = src[sx]*8;
|
||||
row[dx] = t0; row[dx + cn] = t1;
|
||||
|
||||
if (dst_width > src_width*2)
|
||||
{
|
||||
row[(dst_width-1) * cn + x] = row[dx + cn];
|
||||
}
|
||||
}
|
||||
|
||||
pyrUpVec0<RVV>()(src, row, reinterpret_cast<const uint*>(dtab), cn, src_width - cn);
|
||||
}
|
||||
|
||||
// do vertical convolution and decimation and write the result to the destination image
|
||||
for( k = 0; k < PU_SZ; k++ )
|
||||
rows[k] = buf + ((y - PU_SZ/2 + k - sy0) % PU_SZ)*bufstep;
|
||||
row0 = rows[0]; row1 = rows[1]; row2 = rows[2];
|
||||
|
||||
pyrUpVec1<RVV>()(row0, row1, row2, dst0, dst1, dst_width);
|
||||
}
|
||||
|
||||
if (dst_height > src_height*2)
|
||||
{
|
||||
T* dst0 = reinterpret_cast<T*>(dst_data + dst_step * (src_height*2-2));
|
||||
T* dst2 = reinterpret_cast<T*>(dst_data + dst_step * (src_height*2));
|
||||
|
||||
for(x = 0; x < dst_width ; x++ )
|
||||
{
|
||||
dst2[x] = dst0[x];
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int pyrDown(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int depth, int cn, int border_type)
|
||||
{
|
||||
if (border_type == BORDER_CONSTANT || (depth == CV_32F && cn == 1))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8U:
|
||||
return pyrDown<rvv<uchar>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, border_type);
|
||||
case CV_16S:
|
||||
return pyrDown<rvv<short>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, border_type);
|
||||
case CV_32F:
|
||||
return pyrDown<rvv<float>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, border_type);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
inline int pyrUp(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int depth, int cn, int border_type)
|
||||
{
|
||||
if (border_type != BORDER_DEFAULT)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8U:
|
||||
return pyrUp<rvv<uchar>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn);
|
||||
case CV_16S:
|
||||
return pyrUp<rvv<short>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn);
|
||||
case CV_32F:
|
||||
return pyrUp<rvv<float>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Vendored
+173
@@ -0,0 +1,173 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_QR_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_QR_HPP_INCLUDED
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
#include <riscv_vector.h>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv { namespace qr {
|
||||
|
||||
#undef cv_hal_QR32f
|
||||
#define cv_hal_QR32f cv::cv_hal_rvv::qr::QR<cv::cv_hal_rvv::RVV_F32M4>
|
||||
#undef cv_hal_QR64f
|
||||
#define cv_hal_QR64f cv::cv_hal_rvv::qr::QR<cv::cv_hal_rvv::RVV_F64M4>
|
||||
|
||||
// the algorithm is copied from core/src/matrix_decomp.cpp,
|
||||
// in the function template static int cv::QRImpl
|
||||
template<typename RVV_T, typename T = typename RVV_T::ElemType>
|
||||
inline int QR(T* src1, size_t src1_step, int m, int n, int k, T* src2, size_t src2_step, T* dst, int* info)
|
||||
{
|
||||
T eps;
|
||||
if (typeid(T) == typeid(float))
|
||||
eps = FLT_EPSILON*10;
|
||||
else if (typeid(T) == typeid(double))
|
||||
eps = DBL_EPSILON*400;
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
src1_step /= sizeof(T);
|
||||
src2_step /= sizeof(T);
|
||||
|
||||
size_t buf_size = m ? m + n : dst != NULL;
|
||||
std::vector<T> buffer(buf_size);
|
||||
T* val = buffer.data();
|
||||
if (dst == NULL)
|
||||
dst = val + m;
|
||||
|
||||
int vlmax = RVV_T::setvlmax(), vl;
|
||||
for (int l = 0; l < n; l++)
|
||||
{
|
||||
//generate val
|
||||
int vlSize = m - l;
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for (int i = 0; i < vlSize; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(vlSize - i);
|
||||
auto vec_src = RVV_T::vload_stride(src1 + (l + i) * src1_step + l, sizeof(T) * src1_step, vl);
|
||||
RVV_T::vstore(val + i, vec_src, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src, vec_src, vl);
|
||||
}
|
||||
T vlNorm = __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
T tmpV = val[0];
|
||||
val[0] = val[0] + (val[0] >= 0 ? 1 : -1) * std::sqrt(vlNorm);
|
||||
vlNorm = std::sqrt(vlNorm + val[0] * val[0] - tmpV*tmpV);
|
||||
for (int i = 0; i < vlSize; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(vlSize - i);
|
||||
auto vec_src = RVV_T::vload(val + i, vl);
|
||||
vec_src = __riscv_vfdiv(vec_src, vlNorm, vl);
|
||||
RVV_T::vstore(val + i, vec_src, vl);
|
||||
}
|
||||
//multiply A_l*val
|
||||
for (int j = l; j < n; j++)
|
||||
{
|
||||
vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for (int i = l; i < m; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(m - i);
|
||||
auto vec_src1 = RVV_T::vload(val + i - l, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src1 + i * src1_step + j, sizeof(T) * src1_step, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
T v_lA = 2 * __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
|
||||
for (int i = l; i < m; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(m - i);
|
||||
auto vec_src1 = RVV_T::vload(val + i - l, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src1 + i * src1_step + j, sizeof(T) * src1_step, vl);
|
||||
vec_src2 = __riscv_vfnmsac(vec_src2, v_lA, vec_src1, vl);
|
||||
RVV_T::vstore_stride(src1 + i * src1_step + j, sizeof(T) * src1_step, vec_src2, vl);
|
||||
}
|
||||
}
|
||||
|
||||
//save val and factors
|
||||
dst[l] = val[0] * val[0];
|
||||
for (int i = 1; i < vlSize; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(vlSize - i);
|
||||
auto vec_src = RVV_T::vload(val + i, vl);
|
||||
vec_src = __riscv_vfdiv(vec_src, val[0], vl);
|
||||
RVV_T::vstore_stride(src1 + (l + i) * src1_step + l, sizeof(T) * src1_step, vec_src, vl);
|
||||
}
|
||||
}
|
||||
|
||||
if (src2)
|
||||
{
|
||||
//generate new rhs
|
||||
for (int l = 0; l < n; l++)
|
||||
{
|
||||
//unpack val
|
||||
val[0] = (T)1;
|
||||
for (int j = 1; j < m - l; j += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(m - l - j);
|
||||
auto vec_src = RVV_T::vload_stride(src1 + (j + l) * src1_step + l, sizeof(T) * src1_step, vl);
|
||||
RVV_T::vstore(val + j, vec_src, vl);
|
||||
}
|
||||
|
||||
//h_l*x
|
||||
for (int j = 0; j < k; j++)
|
||||
{
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for (int i = l; i < m; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(m - i);
|
||||
auto vec_src1 = RVV_T::vload(val + i - l, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src2 + i * src2_step + j, sizeof(T) * src2_step, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
T v_lB = 2 * dst[l] * __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
|
||||
for (int i = l; i < m; i += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(m - i);
|
||||
auto vec_src1 = RVV_T::vload(val + i - l, vl);
|
||||
auto vec_src2 = RVV_T::vload_stride(src2 + i * src2_step + j, sizeof(T) * src2_step, vl);
|
||||
vec_src2 = __riscv_vfnmsac(vec_src2, v_lB, vec_src1, vl);
|
||||
RVV_T::vstore_stride(src2 + i * src2_step + j, sizeof(T) * src2_step, vec_src2, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
//do back substitution
|
||||
for (int i = n - 1; i >= 0; i--)
|
||||
{
|
||||
for (int j = n - 1; j > i; j--)
|
||||
{
|
||||
for (int p = 0; p < k; p += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(k - p);
|
||||
auto vec_src1 = RVV_T::vload(src2 + i * src2_step + p, vl);
|
||||
auto vec_src2 = RVV_T::vload(src2 + j * src2_step + p, vl);
|
||||
vec_src1 = __riscv_vfnmsac(vec_src1, src1[i*src1_step + j], vec_src2, vl);
|
||||
RVV_T::vstore(src2 + i * src2_step + p, vec_src1, vl);
|
||||
}
|
||||
}
|
||||
if (std::abs(src1[i*src1_step + i]) < eps)
|
||||
{
|
||||
*info = 0;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
for (int p = 0; p < k; p += vl)
|
||||
{
|
||||
vl = RVV_T::setvl(k - p);
|
||||
auto vec_src = RVV_T::vload(src2 + i * src2_step + p, vl);
|
||||
vec_src = __riscv_vfdiv(vec_src, src1[i*src1_step + i], vl);
|
||||
RVV_T::vstore(src2 + i * src2_step + p, vec_src, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*info = 1;
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Vendored
+268
@@ -0,0 +1,268 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HAL_RVV_SVD_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_SVD_HPP_INCLUDED
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
#include <riscv_vector.h>
|
||||
#include "hal_rvv_1p0/types.hpp"
|
||||
|
||||
namespace cv { namespace cv_hal_rvv { namespace svd {
|
||||
|
||||
#undef cv_hal_SVD32f
|
||||
#define cv_hal_SVD32f cv::cv_hal_rvv::svd::SVD<cv::cv_hal_rvv::RVV_F32M4>
|
||||
#undef cv_hal_SVD64f
|
||||
#define cv_hal_SVD64f cv::cv_hal_rvv::svd::SVD<cv::cv_hal_rvv::RVV_F64M4>
|
||||
|
||||
// the algorithm is copied from core/src/lapack.cpp,
|
||||
// in the function template static void cv::JacobiSVDImpl_
|
||||
template<typename RVV_T, typename T = typename RVV_T::ElemType>
|
||||
inline int SVD(T* src, size_t src_step, T* w, T*, size_t, T* vt, size_t vt_step, int m, int n, int flags)
|
||||
{
|
||||
T minval, eps;
|
||||
if( typeid(T) == typeid(float) )
|
||||
{
|
||||
minval = FLT_MIN;
|
||||
eps = FLT_EPSILON*2;
|
||||
}
|
||||
else if( typeid(T) == typeid(double) )
|
||||
{
|
||||
minval = DBL_MIN;
|
||||
eps = DBL_EPSILON*10;
|
||||
}
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int n1;
|
||||
if( flags == CV_HAL_SVD_NO_UV )
|
||||
n1 = 0;
|
||||
else if( flags == (CV_HAL_SVD_SHORT_UV | CV_HAL_SVD_MODIFY_A) )
|
||||
n1 = n;
|
||||
else if( flags == (CV_HAL_SVD_FULL_UV | CV_HAL_SVD_MODIFY_A) )
|
||||
n1 = m;
|
||||
else
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
std::vector<double> Wbuf(n);
|
||||
double* W = Wbuf.data();
|
||||
int i, j, k, iter, max_iter = std::max(m, 30);
|
||||
T c, s;
|
||||
double sd;
|
||||
src_step /= sizeof(src[0]);
|
||||
vt_step /= sizeof(vt[0]);
|
||||
|
||||
int vlmax = RVV_T::setvlmax(), vl;
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
for( k = 0, sd = 0; k < m; k++ )
|
||||
{
|
||||
T t = src[i*src_step + k];
|
||||
sd += (double)t*t;
|
||||
}
|
||||
W[i] = sd;
|
||||
|
||||
if( vt )
|
||||
{
|
||||
for( k = 0; k < n; k++ )
|
||||
vt[i*vt_step + k] = 0;
|
||||
vt[i*vt_step + i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for( iter = 0; iter < max_iter; iter++ )
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
for( i = 0; i < n-1; i++ )
|
||||
for( j = i+1; j < n; j++ )
|
||||
{
|
||||
T *Ai = src + i*src_step, *Aj = src + j*src_step;
|
||||
double a = W[i], p = 0, b = W[j];
|
||||
|
||||
auto vec_sum1 = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload(Ai + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(Aj + k, vl);
|
||||
vec_sum1 = __riscv_vfmacc_tu(vec_sum1, vec_src1, vec_src2, vl);
|
||||
}
|
||||
p = __riscv_vfmv_f(__riscv_vfredosum(vec_sum1, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
|
||||
if( std::abs(p) <= eps*std::sqrt((double)a*b) )
|
||||
continue;
|
||||
|
||||
p *= 2;
|
||||
double beta = a - b, gamma = hypot((double)p, beta);
|
||||
if( beta < 0 )
|
||||
{
|
||||
double delta = (gamma - beta)*0.5;
|
||||
s = (T)std::sqrt(delta/gamma);
|
||||
c = (T)(p/(gamma*s*2));
|
||||
}
|
||||
else
|
||||
{
|
||||
c = (T)std::sqrt((gamma + beta)/(gamma*2));
|
||||
s = (T)(p/(gamma*c*2));
|
||||
}
|
||||
|
||||
vec_sum1 = RVV_T::vmv(0, vlmax);
|
||||
auto vec_sum2 = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload(Ai + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(Aj + k, vl);
|
||||
auto vec_t0 = __riscv_vfadd(__riscv_vfmul(vec_src1, c, vl), __riscv_vfmul(vec_src2, s, vl), vl);
|
||||
auto vec_t1 = __riscv_vfsub(__riscv_vfmul(vec_src2, c, vl), __riscv_vfmul(vec_src1, s, vl), vl);
|
||||
RVV_T::vstore(Ai + k, vec_t0, vl);
|
||||
RVV_T::vstore(Aj + k, vec_t1, vl);
|
||||
vec_sum1 = __riscv_vfmacc_tu(vec_sum1, vec_t0, vec_t0, vl);
|
||||
vec_sum2 = __riscv_vfmacc_tu(vec_sum2, vec_t1, vec_t1, vl);
|
||||
}
|
||||
W[i] = __riscv_vfmv_f(__riscv_vfredosum(vec_sum1, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
W[j] = __riscv_vfmv_f(__riscv_vfredosum(vec_sum2, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
|
||||
changed = true;
|
||||
|
||||
if( vt )
|
||||
{
|
||||
T *Vi = vt + i*vt_step, *Vj = vt + j*vt_step;
|
||||
for( k = 0; k < n; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(n - k);
|
||||
auto vec_src1 = RVV_T::vload(Vi + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(Vj + k, vl);
|
||||
auto vec_t0 = __riscv_vfadd(__riscv_vfmul(vec_src1, c, vl), __riscv_vfmul(vec_src2, s, vl), vl);
|
||||
auto vec_t1 = __riscv_vfsub(__riscv_vfmul(vec_src2, c, vl), __riscv_vfmul(vec_src1, s, vl), vl);
|
||||
RVV_T::vstore(Vi + k, vec_t0, vl);
|
||||
RVV_T::vstore(Vj + k, vec_t1, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !changed )
|
||||
break;
|
||||
}
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src = RVV_T::vload(src + i * src_step + k, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src, vec_src, vl);
|
||||
}
|
||||
W[i] = std::sqrt(__riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax)));
|
||||
}
|
||||
|
||||
for( i = 0; i < n-1; i++ )
|
||||
{
|
||||
j = i;
|
||||
for( k = i+1; k < n; k++ )
|
||||
{
|
||||
if( W[j] < W[k] )
|
||||
j = k;
|
||||
}
|
||||
if( i != j )
|
||||
{
|
||||
std::swap(W[i], W[j]);
|
||||
if( vt )
|
||||
{
|
||||
for( k = 0; k < m; k++ )
|
||||
std::swap(src[i*src_step + k], src[j*src_step + k]);
|
||||
|
||||
for( k = 0; k < n; k++ )
|
||||
std::swap(vt[i*vt_step + k], vt[j*vt_step + k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
w[i] = (T)W[i];
|
||||
|
||||
if( !vt )
|
||||
return CV_HAL_ERROR_OK;
|
||||
|
||||
for( i = 0; i < n1; i++ )
|
||||
{
|
||||
sd = i < n ? W[i] : 0;
|
||||
|
||||
for( int ii = 0; ii < 100 && sd <= minval; ii++ )
|
||||
{
|
||||
// if we got a zero singular value, then in order to get the corresponding left singular vector
|
||||
// we generate a random vector, project it to the previously computed left singular vectors,
|
||||
// subtract the projection and normalize the difference.
|
||||
const T val0 = (T)(1./m);
|
||||
for( k = 0; k < m; k++ )
|
||||
{
|
||||
T val = (rand() & 256) != 0 ? val0 : -val0;
|
||||
src[i*src_step + k] = val;
|
||||
}
|
||||
for( iter = 0; iter < 2; iter++ )
|
||||
{
|
||||
for( j = 0; j < i; j++ )
|
||||
{
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload(src + i * src_step + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(src + j * src_step + k, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
sd = __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
|
||||
vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload(src + i * src_step + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(src + j * src_step + k, vl);
|
||||
vec_src1 = __riscv_vfnmsac(vec_src1, sd, vec_src2, vl);
|
||||
RVV_T::vstore(src + i * src_step + k, vec_src1, vl);
|
||||
vec_sum = __riscv_vfadd_tu(vec_sum, vec_sum, __riscv_vfabs(vec_src1, vl), vl);
|
||||
}
|
||||
T asum = __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
|
||||
asum = asum > eps*100 ? 1/asum : 0;
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src = RVV_T::vload(src + i * src_step + k, vl);
|
||||
vec_src = __riscv_vfmul(vec_src, asum, vl);
|
||||
RVV_T::vstore(src + i * src_step + k, vec_src, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto vec_sum = RVV_T::vmv(0, vlmax);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src1 = RVV_T::vload(src + i * src_step + k, vl);
|
||||
auto vec_src2 = RVV_T::vload(src + j * src_step + k, vl);
|
||||
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
|
||||
}
|
||||
sd = std::sqrt(__riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax)));
|
||||
}
|
||||
|
||||
s = (T)(sd > minval ? 1/sd : 0.);
|
||||
for( k = 0; k < m; k += vl )
|
||||
{
|
||||
vl = RVV_T::setvl(m - k);
|
||||
auto vec_src = RVV_T::vload(src + i * src_step + k, vl);
|
||||
vec_src = __riscv_vfmul(vec_src, s, vl);
|
||||
RVV_T::vstore(src + i * src_step + k, vec_src, vl);
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+485
@@ -0,0 +1,485 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level
|
||||
// directory of this distribution and at http://opencv.org/license.html.
|
||||
#pragma once
|
||||
|
||||
#include <riscv_vector.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace cv { namespace cv_hal_rvv {
|
||||
|
||||
enum RVV_LMUL
|
||||
{
|
||||
LMUL_1 = 1,
|
||||
LMUL_2 = 2,
|
||||
LMUL_4 = 4,
|
||||
LMUL_8 = 8,
|
||||
LMUL_f2,
|
||||
LMUL_f4,
|
||||
LMUL_f8,
|
||||
};
|
||||
|
||||
template <typename T, RVV_LMUL LMUL>
|
||||
struct RVV;
|
||||
|
||||
// -------------------------------Supported types--------------------------------
|
||||
|
||||
using RVV_U8M1 = struct RVV<uint8_t, LMUL_1>;
|
||||
using RVV_U8M2 = struct RVV<uint8_t, LMUL_2>;
|
||||
using RVV_U8M4 = struct RVV<uint8_t, LMUL_4>;
|
||||
using RVV_U8M8 = struct RVV<uint8_t, LMUL_8>;
|
||||
using RVV_U8MF2 = struct RVV<uint8_t, LMUL_f2>;
|
||||
using RVV_U8MF4 = struct RVV<uint8_t, LMUL_f4>;
|
||||
using RVV_U8MF8 = struct RVV<uint8_t, LMUL_f8>;
|
||||
|
||||
using RVV_I8M1 = struct RVV<int8_t, LMUL_1>;
|
||||
using RVV_I8M2 = struct RVV<int8_t, LMUL_2>;
|
||||
using RVV_I8M4 = struct RVV<int8_t, LMUL_4>;
|
||||
using RVV_I8M8 = struct RVV<int8_t, LMUL_8>;
|
||||
using RVV_I8MF2 = struct RVV<int8_t, LMUL_f2>;
|
||||
using RVV_I8MF4 = struct RVV<int8_t, LMUL_f4>;
|
||||
using RVV_I8MF8 = struct RVV<int8_t, LMUL_f8>;
|
||||
|
||||
using RVV_U16M1 = struct RVV<uint16_t, LMUL_1>;
|
||||
using RVV_U16M2 = struct RVV<uint16_t, LMUL_2>;
|
||||
using RVV_U16M4 = struct RVV<uint16_t, LMUL_4>;
|
||||
using RVV_U16M8 = struct RVV<uint16_t, LMUL_8>;
|
||||
using RVV_U16MF2 = struct RVV<uint16_t, LMUL_f2>;
|
||||
using RVV_U16MF4 = struct RVV<uint16_t, LMUL_f4>;
|
||||
|
||||
using RVV_I16M1 = struct RVV<int16_t, LMUL_1>;
|
||||
using RVV_I16M2 = struct RVV<int16_t, LMUL_2>;
|
||||
using RVV_I16M4 = struct RVV<int16_t, LMUL_4>;
|
||||
using RVV_I16M8 = struct RVV<int16_t, LMUL_8>;
|
||||
using RVV_I16MF2 = struct RVV<int16_t, LMUL_f2>;
|
||||
using RVV_I16MF4 = struct RVV<int16_t, LMUL_f4>;
|
||||
|
||||
using RVV_U32M1 = struct RVV<uint32_t, LMUL_1>;
|
||||
using RVV_U32M2 = struct RVV<uint32_t, LMUL_2>;
|
||||
using RVV_U32M4 = struct RVV<uint32_t, LMUL_4>;
|
||||
using RVV_U32M8 = struct RVV<uint32_t, LMUL_8>;
|
||||
using RVV_U32MF2 = struct RVV<uint32_t, LMUL_f2>;
|
||||
|
||||
using RVV_I32M1 = struct RVV<int32_t, LMUL_1>;
|
||||
using RVV_I32M2 = struct RVV<int32_t, LMUL_2>;
|
||||
using RVV_I32M4 = struct RVV<int32_t, LMUL_4>;
|
||||
using RVV_I32M8 = struct RVV<int32_t, LMUL_8>;
|
||||
using RVV_I32MF2 = struct RVV<int32_t, LMUL_f2>;
|
||||
|
||||
using RVV_U64M1 = struct RVV<uint64_t, LMUL_1>;
|
||||
using RVV_U64M2 = struct RVV<uint64_t, LMUL_2>;
|
||||
using RVV_U64M4 = struct RVV<uint64_t, LMUL_4>;
|
||||
using RVV_U64M8 = struct RVV<uint64_t, LMUL_8>;
|
||||
|
||||
using RVV_I64M1 = struct RVV<int64_t, LMUL_1>;
|
||||
using RVV_I64M2 = struct RVV<int64_t, LMUL_2>;
|
||||
using RVV_I64M4 = struct RVV<int64_t, LMUL_4>;
|
||||
using RVV_I64M8 = struct RVV<int64_t, LMUL_8>;
|
||||
|
||||
using RVV_F32M1 = struct RVV<float, LMUL_1>;
|
||||
using RVV_F32M2 = struct RVV<float, LMUL_2>;
|
||||
using RVV_F32M4 = struct RVV<float, LMUL_4>;
|
||||
using RVV_F32M8 = struct RVV<float, LMUL_8>;
|
||||
using RVV_F32MF2 = struct RVV<float, LMUL_f2>;
|
||||
|
||||
using RVV_F64M1 = struct RVV<double, LMUL_1>;
|
||||
using RVV_F64M2 = struct RVV<double, LMUL_2>;
|
||||
using RVV_F64M4 = struct RVV<double, LMUL_4>;
|
||||
using RVV_F64M8 = struct RVV<double, LMUL_8>;
|
||||
|
||||
// Only for dst type lmul >= 1
|
||||
template <typename Dst_T, typename RVV_T>
|
||||
using RVV_SameLen =
|
||||
RVV<Dst_T, RVV_LMUL(RVV_T::lmul / sizeof(typename RVV_T::ElemType) * sizeof(Dst_T))>;
|
||||
|
||||
template <typename RVV_T>
|
||||
using RVV_BaseType = RVV<typename RVV_T::ElemType, LMUL_1>;
|
||||
|
||||
// -------------------------------Supported operations--------------------------------
|
||||
|
||||
#define HAL_RVV_SIZE_RELATED(EEW, TYPE, LMUL, S_OR_F, X_OR_F, IS_U, IS_F) \
|
||||
static inline size_t setvlmax() { return __riscv_vsetvlmax_e##EEW##LMUL(); } \
|
||||
static inline size_t setvl(size_t vl) { return __riscv_vsetvl_e##EEW##LMUL(vl); } \
|
||||
static inline VecType vload(const ElemType* ptr, size_t vl) { \
|
||||
return __riscv_vle##EEW##_v_##TYPE##LMUL(ptr, vl); \
|
||||
} \
|
||||
static inline VecType vload(BoolType vm, const ElemType* ptr, size_t vl) { \
|
||||
return __riscv_vle##EEW(vm, ptr, vl); \
|
||||
} \
|
||||
static inline VecType vload_stride(const ElemType* ptr, ptrdiff_t unit, size_t vl) { \
|
||||
return __riscv_vlse##EEW##_v_##TYPE##LMUL(ptr, unit, vl); \
|
||||
} \
|
||||
static inline VecType vload_stride(BoolType vm, const ElemType* ptr, ptrdiff_t unit, size_t vl) { \
|
||||
return __riscv_vlse##EEW(vm, ptr, unit, vl); \
|
||||
} \
|
||||
static inline void vstore(ElemType* ptr, VecType v, size_t vl) { \
|
||||
__riscv_vse##EEW(ptr, v, vl); \
|
||||
} \
|
||||
static inline void vstore(BoolType vm, ElemType* ptr, VecType v, size_t vl) { \
|
||||
__riscv_vse##EEW(vm, ptr, v, vl); \
|
||||
} \
|
||||
static inline void vstore_stride(ElemType* ptr, ptrdiff_t unit, VecType v, size_t vl) { \
|
||||
__riscv_vsse##EEW(ptr, unit, v, vl); \
|
||||
} \
|
||||
static inline void vstore_stride(BoolType vm, ElemType* ptr, ptrdiff_t unit, VecType v, size_t vl) { \
|
||||
__riscv_vsse##EEW(vm, ptr, unit, v, vl); \
|
||||
} \
|
||||
static inline VecType vundefined() { return __riscv_vundefined_##TYPE##LMUL(); } \
|
||||
static inline VecType vmv(ElemType a, size_t vl) { \
|
||||
return __riscv_v##IS_F##mv_v_##X_OR_F##_##TYPE##LMUL(a, vl); \
|
||||
} \
|
||||
static inline VecType vmv_s(ElemType a, size_t vl) { \
|
||||
return __riscv_v##IS_F##mv_s_##X_OR_F##_##TYPE##LMUL(a, vl); \
|
||||
} \
|
||||
HAL_RVV_SIZE_RELATED_CUSTOM(EEW, TYPE, LMUL)
|
||||
|
||||
#define HAL_RVV_SIZE_UNRELATED(S_OR_F, X_OR_F, IS_U, IS_F) \
|
||||
static inline ElemType vmv_x(VecType vs2) { return __riscv_v##IS_F##mv_##X_OR_F(vs2); } \
|
||||
\
|
||||
static inline BoolType vmlt(VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##lt##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmle(VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##le##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmgt(VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##gt##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmge(VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##ge##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmlt_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##lt##IS_U##_mu(vm, vd, vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmle_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##le##IS_U##_mu(vm, vd, vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmgt_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##gt##IS_U##_mu(vm, vd, vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BoolType vmge_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_vm##S_OR_F##ge##IS_U##_mu(vm, vd, vs2, vs1, vl); \
|
||||
} \
|
||||
\
|
||||
static inline VecType vmin(VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##min##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline VecType vmax(VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##max##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline VecType vmin_tu(VecType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##min##IS_U##_tu(vd, vs2, vs1, vl); \
|
||||
} \
|
||||
static inline VecType vmax_tu(VecType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##max##IS_U##_tu(vd, vs2, vs1, vl); \
|
||||
} \
|
||||
static inline VecType vmin_tumu(BoolType vm, VecType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##min##IS_U##_tumu(vm, vd, vs2, vs1, vl); \
|
||||
} \
|
||||
static inline VecType vmax_tumu(BoolType vm, VecType vd, VecType vs2, VecType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##max##IS_U##_tumu(vm, vd, vs2, vs1, vl); \
|
||||
} \
|
||||
\
|
||||
static inline BaseType vredmin(VecType vs2, BaseType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##redmin##IS_U(vs2, vs1, vl); \
|
||||
} \
|
||||
static inline BaseType vredmax(VecType vs2, BaseType vs1, size_t vl) { \
|
||||
return __riscv_v##IS_F##redmax##IS_U(vs2, vs1, vl); \
|
||||
}
|
||||
|
||||
#define HAL_RVV_BOOL_TYPE(S_OR_F, X_OR_F, IS_U, IS_F) \
|
||||
decltype(__riscv_vm##S_OR_F##eq(std::declval<VecType>(), std::declval<VecType>(), 0))
|
||||
|
||||
#define HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_TYPE, \
|
||||
EEW, TYPE, LMUL, ...) \
|
||||
template <> struct RVV<ELEM_TYPE, LMUL_TYPE> \
|
||||
{ \
|
||||
using ElemType = ELEM_TYPE; \
|
||||
using VecType = v##VEC_TYPE##LMUL##_t; \
|
||||
using BoolType = HAL_RVV_BOOL_TYPE(__VA_ARGS__); \
|
||||
using BaseType = v##VEC_TYPE##m1_t; \
|
||||
\
|
||||
static constexpr size_t lmul = LMUL_TYPE; \
|
||||
\
|
||||
HAL_RVV_SIZE_RELATED(EEW, TYPE, LMUL, __VA_ARGS__) \
|
||||
HAL_RVV_SIZE_UNRELATED(__VA_ARGS__) \
|
||||
\
|
||||
template <typename FROM> \
|
||||
inline static VecType cast(FROM v, size_t vl); \
|
||||
}; \
|
||||
\
|
||||
template <> \
|
||||
inline RVV<ELEM_TYPE, LMUL_TYPE>::VecType \
|
||||
RVV<ELEM_TYPE, LMUL_TYPE>::cast( \
|
||||
RVV<ELEM_TYPE, LMUL_TYPE>::VecType v, \
|
||||
[[maybe_unused]] size_t vl \
|
||||
) \
|
||||
{ \
|
||||
return v; \
|
||||
}
|
||||
|
||||
// -------------------------------Define all types--------------------------------
|
||||
|
||||
#define HAL_RVV_DEFINE_ALL(ELEM_TYPE, VEC_TYPE, \
|
||||
EEW, TYPE, ...) \
|
||||
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_1, \
|
||||
EEW, TYPE, m1, __VA_ARGS__) \
|
||||
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_2, \
|
||||
EEW, TYPE, m2, __VA_ARGS__) \
|
||||
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_4, \
|
||||
EEW, TYPE, m4, __VA_ARGS__) \
|
||||
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_8, \
|
||||
EEW, TYPE, m8, __VA_ARGS__)
|
||||
|
||||
#define HAL_RVV_SIGNED_PARAM s,x, ,
|
||||
#define HAL_RVV_UNSIGNED_PARAM s,x,u,
|
||||
#define HAL_RVV_FLOAT_PARAM f,f, ,f
|
||||
|
||||
// -------------------------------Define Unsigned Integer--------------------------------
|
||||
|
||||
#define HAL_RVV_SIZE_RELATED_CUSTOM(EEW, TYPE, LMUL) \
|
||||
static inline VecType vid(size_t vl) { return __riscv_vid_v_##TYPE##LMUL(vl); }
|
||||
|
||||
// LMUL = 1, 2, 4, 8
|
||||
HAL_RVV_DEFINE_ALL( uint8_t, uint8, 8, u8, HAL_RVV_UNSIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(uint16_t, uint16, 16, u16, HAL_RVV_UNSIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(uint32_t, uint32, 32, u32, HAL_RVV_UNSIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(uint64_t, uint64, 64, u64, HAL_RVV_UNSIGNED_PARAM)
|
||||
|
||||
// LMUL = f2
|
||||
HAL_RVV_DEFINE_ONE( uint8_t, uint8, LMUL_f2, 8, u8, mf2, HAL_RVV_UNSIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ONE(uint16_t, uint16, LMUL_f2, 16, u16, mf2, HAL_RVV_UNSIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ONE(uint32_t, uint32, LMUL_f2, 32, u32, mf2, HAL_RVV_UNSIGNED_PARAM)
|
||||
|
||||
// LMUL = f4
|
||||
HAL_RVV_DEFINE_ONE( uint8_t, uint8, LMUL_f4, 8, u8, mf4, HAL_RVV_UNSIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ONE(uint16_t, uint16, LMUL_f4, 16, u16, mf4, HAL_RVV_UNSIGNED_PARAM)
|
||||
|
||||
// LMUL = f8
|
||||
HAL_RVV_DEFINE_ONE( uint8_t, uint8, LMUL_f8, 8, u8, mf8, HAL_RVV_UNSIGNED_PARAM)
|
||||
|
||||
#undef HAL_RVV_SIZE_RELATED_CUSTOM
|
||||
|
||||
// -------------------------------Define Signed Integer--------------------------------
|
||||
|
||||
#define HAL_RVV_SIZE_RELATED_CUSTOM(EEW, TYPE, LMUL)
|
||||
|
||||
// LMUL = 1, 2, 4, 8
|
||||
HAL_RVV_DEFINE_ALL( int8_t, int8, 8, i8, HAL_RVV_SIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(int16_t, int16, 16, i16, HAL_RVV_SIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(int32_t, int32, 32, i32, HAL_RVV_SIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(int64_t, int64, 64, i64, HAL_RVV_SIGNED_PARAM)
|
||||
|
||||
// LMUL = f2
|
||||
HAL_RVV_DEFINE_ONE( int8_t, int8, LMUL_f2, 8, i8, mf2, HAL_RVV_SIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ONE(int16_t, int16, LMUL_f2, 16, i16, mf2, HAL_RVV_SIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ONE(int32_t, int32, LMUL_f2, 32, i32, mf2, HAL_RVV_SIGNED_PARAM)
|
||||
|
||||
// LMUL = f4
|
||||
HAL_RVV_DEFINE_ONE( int8_t, int8, LMUL_f4, 8, i8, mf4, HAL_RVV_SIGNED_PARAM)
|
||||
HAL_RVV_DEFINE_ONE(int16_t, int16, LMUL_f4, 16, i16, mf4, HAL_RVV_SIGNED_PARAM)
|
||||
|
||||
// LMUL = f8
|
||||
HAL_RVV_DEFINE_ONE( int8_t, int8, LMUL_f8, 8, i8, mf8, HAL_RVV_SIGNED_PARAM)
|
||||
|
||||
// -------------------------------Define Floating Point--------------------------------
|
||||
|
||||
// LMUL = 1, 2, 4, 8
|
||||
HAL_RVV_DEFINE_ALL( float, float32, 32, f32, HAL_RVV_FLOAT_PARAM)
|
||||
HAL_RVV_DEFINE_ALL(double, float64, 64, f64, HAL_RVV_FLOAT_PARAM)
|
||||
|
||||
// LMUL = f2
|
||||
HAL_RVV_DEFINE_ONE( float, float32, LMUL_f2, 32, f32, mf2, HAL_RVV_FLOAT_PARAM)
|
||||
|
||||
#undef HAL_RVV_SIZE_RELATED_CUSTOM
|
||||
#undef HAL_RVV_DEFINE_ALL
|
||||
#undef HAL_RVV_DEFINE_ONE
|
||||
#undef HAL_RVV_BOOL_TYPE
|
||||
#undef HAL_RVV_SIZE_UNRELATED
|
||||
#undef HAL_RVV_SIZE_RELATED
|
||||
|
||||
// -------------------------------Define cast--------------------------------
|
||||
|
||||
#define HAL_RVV_CVT(ONE, TWO) \
|
||||
template <> \
|
||||
inline ONE::VecType ONE::cast(TWO::VecType v, size_t vl) { return __riscv_vncvt_x(v, vl); } \
|
||||
template <> \
|
||||
inline TWO::VecType TWO::cast(ONE::VecType v, size_t vl) { return __riscv_vwcvt_x(v, vl); }
|
||||
|
||||
HAL_RVV_CVT(RVV_I8M4, RVV_I16M8)
|
||||
HAL_RVV_CVT(RVV_I8M2, RVV_I16M4)
|
||||
HAL_RVV_CVT(RVV_I8M1, RVV_I16M2)
|
||||
HAL_RVV_CVT(RVV_I8MF2, RVV_I16M1)
|
||||
HAL_RVV_CVT(RVV_I8MF4, RVV_I16MF2)
|
||||
HAL_RVV_CVT(RVV_I8MF8, RVV_I16MF4)
|
||||
|
||||
HAL_RVV_CVT(RVV_I16M4, RVV_I32M8)
|
||||
HAL_RVV_CVT(RVV_I16M2, RVV_I32M4)
|
||||
HAL_RVV_CVT(RVV_I16M1, RVV_I32M2)
|
||||
HAL_RVV_CVT(RVV_I16MF2, RVV_I32M1)
|
||||
HAL_RVV_CVT(RVV_I16MF4, RVV_I32MF2)
|
||||
|
||||
HAL_RVV_CVT(RVV_I32M4, RVV_I64M8)
|
||||
HAL_RVV_CVT(RVV_I32M2, RVV_I64M4)
|
||||
HAL_RVV_CVT(RVV_I32M1, RVV_I64M2)
|
||||
HAL_RVV_CVT(RVV_I32MF2, RVV_I64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(ONE, TWO) \
|
||||
template <> \
|
||||
inline ONE::VecType ONE::cast(TWO::VecType v, size_t vl) { return __riscv_vncvt_x(v, vl); } \
|
||||
template <> \
|
||||
inline TWO::VecType TWO::cast(ONE::VecType v, size_t vl) { return __riscv_vwcvtu_x(v, vl); }
|
||||
|
||||
HAL_RVV_CVT(RVV_U8M4, RVV_U16M8)
|
||||
HAL_RVV_CVT(RVV_U8M2, RVV_U16M4)
|
||||
HAL_RVV_CVT(RVV_U8M1, RVV_U16M2)
|
||||
HAL_RVV_CVT(RVV_U8MF2, RVV_U16M1)
|
||||
HAL_RVV_CVT(RVV_U8MF4, RVV_U16MF2)
|
||||
HAL_RVV_CVT(RVV_U8MF8, RVV_U16MF4)
|
||||
|
||||
HAL_RVV_CVT(RVV_U16M4, RVV_U32M8)
|
||||
HAL_RVV_CVT(RVV_U16M2, RVV_U32M4)
|
||||
HAL_RVV_CVT(RVV_U16M1, RVV_U32M2)
|
||||
HAL_RVV_CVT(RVV_U16MF2, RVV_U32M1)
|
||||
HAL_RVV_CVT(RVV_U16MF4, RVV_U32MF2)
|
||||
|
||||
HAL_RVV_CVT(RVV_U32M4, RVV_U64M8)
|
||||
HAL_RVV_CVT(RVV_U32M2, RVV_U64M4)
|
||||
HAL_RVV_CVT(RVV_U32M1, RVV_U64M2)
|
||||
HAL_RVV_CVT(RVV_U32MF2, RVV_U64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(ONE, FOUR) \
|
||||
template <> \
|
||||
inline FOUR::VecType FOUR::cast(ONE::VecType v, size_t vl) { return __riscv_vsext_vf4(v, vl); } \
|
||||
template <> \
|
||||
inline ONE::VecType ONE::cast(FOUR::VecType v, size_t vl) { \
|
||||
return __riscv_vncvt_x(__riscv_vncvt_x(v, vl), vl); \
|
||||
}
|
||||
|
||||
HAL_RVV_CVT(RVV_I8M2, RVV_I32M8)
|
||||
HAL_RVV_CVT(RVV_I8M1, RVV_I32M4)
|
||||
HAL_RVV_CVT(RVV_I8MF2, RVV_I32M2)
|
||||
HAL_RVV_CVT(RVV_I8MF4, RVV_I32M1)
|
||||
HAL_RVV_CVT(RVV_I8MF8, RVV_I32MF2)
|
||||
|
||||
HAL_RVV_CVT(RVV_I16M2, RVV_I64M8)
|
||||
HAL_RVV_CVT(RVV_I16M1, RVV_I64M4)
|
||||
HAL_RVV_CVT(RVV_I16MF2, RVV_I64M2)
|
||||
HAL_RVV_CVT(RVV_I16MF4, RVV_I64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(ONE, FOUR) \
|
||||
template <> \
|
||||
inline FOUR::VecType FOUR::cast(ONE::VecType v, size_t vl) { return __riscv_vzext_vf4(v, vl); } \
|
||||
template <> \
|
||||
inline ONE::VecType ONE::cast(FOUR::VecType v, size_t vl) { \
|
||||
return __riscv_vncvt_x(__riscv_vncvt_x(v, vl), vl); \
|
||||
}
|
||||
|
||||
HAL_RVV_CVT(RVV_U8M2, RVV_U32M8)
|
||||
HAL_RVV_CVT(RVV_U8M1, RVV_U32M4)
|
||||
HAL_RVV_CVT(RVV_U8MF2, RVV_U32M2)
|
||||
HAL_RVV_CVT(RVV_U8MF4, RVV_U32M1)
|
||||
HAL_RVV_CVT(RVV_U8MF8, RVV_U32MF2)
|
||||
|
||||
HAL_RVV_CVT(RVV_U16M2, RVV_U64M8)
|
||||
HAL_RVV_CVT(RVV_U16M1, RVV_U64M4)
|
||||
HAL_RVV_CVT(RVV_U16MF2, RVV_U64M2)
|
||||
HAL_RVV_CVT(RVV_U16MF4, RVV_U64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(ONE, EIGHT) \
|
||||
template <> \
|
||||
inline EIGHT::VecType EIGHT::cast(ONE::VecType v, size_t vl) { return __riscv_vsext_vf8(v, vl); } \
|
||||
template <> \
|
||||
inline ONE::VecType ONE::cast(EIGHT::VecType v, size_t vl) { \
|
||||
return __riscv_vncvt_x(__riscv_vncvt_x(__riscv_vncvt_x(v ,vl), vl), vl); \
|
||||
}
|
||||
|
||||
HAL_RVV_CVT(RVV_I8M1, RVV_I64M8)
|
||||
HAL_RVV_CVT(RVV_I8MF2, RVV_I64M4)
|
||||
HAL_RVV_CVT(RVV_I8MF4, RVV_I64M2)
|
||||
HAL_RVV_CVT(RVV_I8MF8, RVV_I64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(ONE, EIGHT) \
|
||||
template <> \
|
||||
inline EIGHT::VecType EIGHT::cast(ONE::VecType v, size_t vl) { return __riscv_vzext_vf8(v, vl); } \
|
||||
template <> \
|
||||
inline ONE::VecType ONE::cast(EIGHT::VecType v, size_t vl) { \
|
||||
return __riscv_vncvt_x(__riscv_vncvt_x(__riscv_vncvt_x(v ,vl), vl), vl); \
|
||||
}
|
||||
|
||||
HAL_RVV_CVT(RVV_U8M1, RVV_U64M8)
|
||||
HAL_RVV_CVT(RVV_U8MF2, RVV_U64M4)
|
||||
HAL_RVV_CVT(RVV_U8MF4, RVV_U64M2)
|
||||
HAL_RVV_CVT(RVV_U8MF8, RVV_U64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(F32, F64) \
|
||||
template <> \
|
||||
inline F32::VecType F32::cast(F64::VecType v, size_t vl) { return __riscv_vfncvt_f(v, vl); } \
|
||||
template <> \
|
||||
inline F64::VecType F64::cast(F32::VecType v, size_t vl) { return __riscv_vfwcvt_f(v, vl); }
|
||||
|
||||
HAL_RVV_CVT(RVV_F32M4, RVV_F64M8)
|
||||
HAL_RVV_CVT(RVV_F32M2, RVV_F64M4)
|
||||
HAL_RVV_CVT(RVV_F32M1, RVV_F64M2)
|
||||
HAL_RVV_CVT(RVV_F32MF2, RVV_F64M1)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
#define HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_TYPE, LMUL) \
|
||||
template <> \
|
||||
inline RVV<A, LMUL_TYPE>::VecType RVV<A, LMUL_TYPE>::cast( \
|
||||
RVV<B, LMUL_TYPE>::VecType v, [[maybe_unused]] size_t vl \
|
||||
) { \
|
||||
return __riscv_vreinterpret_##A_TYPE##LMUL(v); \
|
||||
} \
|
||||
template <> \
|
||||
inline RVV<B, LMUL_TYPE>::VecType RVV<B, LMUL_TYPE>::cast( \
|
||||
RVV<A, LMUL_TYPE>::VecType v, [[maybe_unused]] size_t vl \
|
||||
) { \
|
||||
return __riscv_vreinterpret_##B_TYPE##LMUL(v); \
|
||||
}
|
||||
|
||||
#define HAL_RVV_CVT2(A, B, A_TYPE, B_TYPE) \
|
||||
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_1, m1) \
|
||||
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_2, m2) \
|
||||
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_4, m4) \
|
||||
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_8, m8)
|
||||
|
||||
HAL_RVV_CVT2( uint8_t, int8_t, u8, i8)
|
||||
HAL_RVV_CVT2(uint16_t, int16_t, u16, i16)
|
||||
HAL_RVV_CVT2(uint32_t, int32_t, u32, i32)
|
||||
HAL_RVV_CVT2(uint64_t, int64_t, u64, i64)
|
||||
|
||||
HAL_RVV_CVT2( int32_t, float, i32, f32)
|
||||
HAL_RVV_CVT2(uint32_t, float, u32, f32)
|
||||
HAL_RVV_CVT2( int64_t, double, i64, f64)
|
||||
HAL_RVV_CVT2(uint64_t, double, u64, f64)
|
||||
|
||||
#undef HAL_RVV_CVT2
|
||||
|
||||
HAL_RVV_CVT( uint8_t, int8_t, u8, i8, LMUL_f2, mf2)
|
||||
HAL_RVV_CVT(uint16_t, int16_t, u16, i16, LMUL_f2, mf2)
|
||||
HAL_RVV_CVT(uint32_t, int32_t, u32, i32, LMUL_f2, mf2)
|
||||
HAL_RVV_CVT( int32_t, float, i32, f32, LMUL_f2, mf2)
|
||||
HAL_RVV_CVT(uint32_t, float, u32, f32, LMUL_f2, mf2)
|
||||
|
||||
HAL_RVV_CVT( uint8_t, int8_t, u8, i8, LMUL_f4, mf4)
|
||||
HAL_RVV_CVT(uint16_t, int16_t, u16, i16, LMUL_f4, mf4)
|
||||
|
||||
HAL_RVV_CVT( uint8_t, int8_t, u8, i8, LMUL_f8, mf8)
|
||||
|
||||
#undef HAL_RVV_CVT
|
||||
|
||||
}} // namespace cv::cv_hal_rvv
|
||||
+2
-2
@@ -18,7 +18,7 @@ if(CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wstringop-overflow)
|
||||
endif()
|
||||
|
||||
set(VERSION 3.0.3)
|
||||
set(VERSION 3.1.0)
|
||||
set(COPYRIGHT_YEAR "1991-2024")
|
||||
string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
|
||||
list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
|
||||
@@ -203,7 +203,7 @@ check_type_size("size_t" SIZE_T)
|
||||
check_type_size("unsigned long" UNSIGNED_LONG)
|
||||
|
||||
if(ENABLE_LIBJPEG_TURBO_SIMD)
|
||||
add_subdirectory(src/simd)
|
||||
add_subdirectory(simd)
|
||||
if(NEON_INTRINSICS)
|
||||
add_definitions(-DNEON_INTRINSICS)
|
||||
endif()
|
||||
|
||||
Vendored
+1
-1
@@ -94,7 +94,7 @@ intended solely for clarification.
|
||||
The Modified (3-clause) BSD License
|
||||
===================================
|
||||
|
||||
Copyright (C)2009-2023 D. R. Commander. All Rights Reserved.<br>
|
||||
Copyright (C)2009-2024 D. R. Commander. All Rights Reserved.<br>
|
||||
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
Vendored
+14
-12
@@ -36,16 +36,18 @@ TO DO Plans for future IJG releases.
|
||||
Other documentation files in the distribution are:
|
||||
|
||||
User documentation:
|
||||
usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
rdjpgcom, and wrjpgcom.
|
||||
*.1 Unix-style man pages for programs (same info as usage.txt).
|
||||
wizard.txt Advanced usage instructions for JPEG wizards only.
|
||||
change.log Version-to-version change highlights.
|
||||
doc/usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
rdjpgcom, and wrjpgcom.
|
||||
doc/*.1 Unix-style man pages for programs (same info as
|
||||
usage.txt).
|
||||
doc/wizard.txt Advanced usage instructions for JPEG wizards only.
|
||||
doc/change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.txt How to use the JPEG library in your own programs.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.txt Overview of the JPEG library's internal structure.
|
||||
coderules.txt Coding style rules --- please read if you contribute code.
|
||||
doc/libjpeg.txt How to use the JPEG library in your own programs.
|
||||
src/example.c Sample code for calling the JPEG library.
|
||||
doc/structure.txt Overview of the JPEG library's internal structure.
|
||||
doc/coderules.txt Coding style rules --- please read if you contribute
|
||||
code.
|
||||
|
||||
Please read at least usage.txt. Some information can also be found in the JPEG
|
||||
FAQ (Frequently Asked Questions) article. See ARCHIVE LOCATIONS below to find
|
||||
@@ -89,9 +91,9 @@ The library is intended to be reused in other applications.
|
||||
In order to support file conversion and viewing software, we have included
|
||||
considerable functionality beyond the bare JPEG coding/decoding capability;
|
||||
for example, the color quantization modules are not strictly part of JPEG
|
||||
decoding, but they are essential for output to colormapped file formats or
|
||||
colormapped displays. These extra functions can be compiled out of the
|
||||
library if not required for a particular application.
|
||||
decoding, but they are essential for output to colormapped file formats. These
|
||||
extra functions can be compiled out of the library if not required for a
|
||||
particular application.
|
||||
|
||||
We have also included "jpegtran", a utility for lossless transcoding between
|
||||
different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
|
||||
|
||||
Vendored
+13
-9
@@ -69,9 +69,12 @@ JPEG images:
|
||||
generating planar YUV images and performing multiple simultaneous lossless
|
||||
transforms on an image. The Java interface for libjpeg-turbo is written on
|
||||
top of the TurboJPEG API. The TurboJPEG API is recommended for first-time
|
||||
users of libjpeg-turbo. Refer to [tjexample.c](tjexample.c) and
|
||||
[TJExample.java](java/TJExample.java) for examples of its usage and to
|
||||
<http://libjpeg-turbo.org/Documentation/Documentation> for API documentation.
|
||||
users of libjpeg-turbo. Refer to [tjcomp.c](src/tjcomp.c),
|
||||
[tjdecomp.c](src/tjdecomp.c), [tjtran.c](src/tjtran.c),
|
||||
[TJComp.java](java/TJComp.java), [TJDecomp.java](java/TJDecomp.java), and
|
||||
[TJTran.java](java/TJTran.java) for examples of its usage and to
|
||||
<https://libjpeg-turbo.org/Documentation/Documentation> for API
|
||||
documentation.
|
||||
|
||||
- **libjpeg API**<br>
|
||||
This is the de facto industry-standard API for compressing and decompressing
|
||||
@@ -79,8 +82,9 @@ JPEG images:
|
||||
more powerful. The libjpeg API implementation in libjpeg-turbo is both
|
||||
API/ABI-compatible and mathematically compatible with libjpeg v6b. It can
|
||||
also optionally be configured to be API/ABI-compatible with libjpeg v7 and v8
|
||||
(see below.) Refer to [cjpeg.c](cjpeg.c) and [djpeg.c](djpeg.c) for examples
|
||||
of its usage and to [libjpeg.txt](libjpeg.txt) for API documentation.
|
||||
(see below.) Refer to [cjpeg.c](src/cjpeg.c) and [djpeg.c](src/djpeg.c) for
|
||||
examples of its usage and to [libjpeg.txt](doc/libjpeg.txt) for API
|
||||
documentation.
|
||||
|
||||
There is no significant performance advantage to either API when both are used
|
||||
to perform similar operations.
|
||||
@@ -132,9 +136,9 @@ extensions at compile time with:
|
||||
|
||||
#ifdef JCS_ALPHA_EXTENSIONS
|
||||
|
||||
[jcstest.c](jcstest.c), located in the libjpeg-turbo source tree, demonstrates
|
||||
how to check for the existence of the colorspace extensions at compile time and
|
||||
run time.
|
||||
[jcstest.c](src/jcstest.c), located in the libjpeg-turbo source tree,
|
||||
demonstrates how to check for the existence of the colorspace extensions at
|
||||
compile time and run time.
|
||||
|
||||
libjpeg v7 and v8 API/ABI Emulation
|
||||
-----------------------------------
|
||||
@@ -199,7 +203,7 @@ supported and which aren't.
|
||||
NOTE: As of this writing, extensive research has been conducted into the
|
||||
usefulness of DCT scaling as a means of data reduction and SmartScale as a
|
||||
means of quality improvement. Readers are invited to peruse the research at
|
||||
<http://www.libjpeg-turbo.org/About/SmartScale> and draw their own conclusions,
|
||||
<https://libjpeg-turbo.org/About/SmartScale> and draw their own conclusions,
|
||||
but it is the general belief of our project that these features have not
|
||||
demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
|
||||
|
||||
|
||||
Vendored
+17
-31
@@ -273,48 +273,33 @@ endif()
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
int16_t input[] = {
|
||||
(int16_t)argc, (int16_t)argc, (int16_t)argc, (int16_t)argc,
|
||||
(int16_t)argc, (int16_t)argc, (int16_t)argc, (int16_t)argc,
|
||||
(int16_t)argc, (int16_t)argc, (int16_t)argc, (int16_t)argc
|
||||
};
|
||||
int16x4x3_t output = vld1_s16_x3(input);
|
||||
int16_t input[12];
|
||||
int16x4x3_t output;
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) input[i] = (int16_t)argc;
|
||||
output = vld1_s16_x3(input);
|
||||
vst3_s16(input, output);
|
||||
return (int)input[0];
|
||||
}" HAVE_VLD1_S16_X3)
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
uint16_t input[] = {
|
||||
(uint16_t)argc, (uint16_t)argc, (uint16_t)argc, (uint16_t)argc,
|
||||
(uint16_t)argc, (uint16_t)argc, (uint16_t)argc, (uint16_t)argc
|
||||
};
|
||||
uint16x4x2_t output = vld1_u16_x2(input);
|
||||
uint16_t input[8];
|
||||
uint16x4x2_t output;
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) input[i] = (uint16_t)argc;
|
||||
output = vld1_u16_x2(input);
|
||||
vst2_u16(input, output);
|
||||
return (int)input[0];
|
||||
}" HAVE_VLD1_U16_X2)
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
uint8_t input[] = {
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc
|
||||
};
|
||||
uint8x16x4_t output = vld1q_u8_x4(input);
|
||||
uint8_t input[64];
|
||||
uint8x16x4_t output;
|
||||
int i;
|
||||
for (i = 0; i < 64; i++) input[i] = (uint8_t)argc;
|
||||
output = vld1q_u8_x4(input);
|
||||
vst4q_u8(input, output);
|
||||
return (int)input[0];
|
||||
}" HAVE_VLD1Q_U8_X4)
|
||||
@@ -369,7 +354,8 @@ if(NOT NEON_INTRINSICS)
|
||||
separate_arguments(CMAKE_ASM_FLAGS_SEP UNIX_COMMAND "${CMAKE_ASM_FLAGS}")
|
||||
execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS_SEP}
|
||||
-x assembler-with-cpp -c ${CMAKE_CURRENT_BINARY_DIR}/gastest.S
|
||||
RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} RESULT_VARIABLE RESULT
|
||||
OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
|
||||
if(NOT RESULT EQUAL 0)
|
||||
message(WARNING "GAS appears to be broken. Using the full Neon SIMD intrinsics implementation.")
|
||||
set(NEON_INTRINSICS 1 CACHE INTERNAL "" FORCE)
|
||||
+6
-5
@@ -2,6 +2,7 @@
|
||||
* jchuff-neon.c - Huffman entropy encoding (32-bit Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,11 +25,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../../src/jinclude.h"
|
||||
#include "../../../src/jpeglib.h"
|
||||
#include "../../../src/jsimd.h"
|
||||
#include "../../../src/jdct.h"
|
||||
#include "../../../src/jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../jchuff.h"
|
||||
#include "neon-compat.h"
|
||||
+6
-6
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2022, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2022, 2024, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, 2022, Matthieu Darbois.
|
||||
* Copyright (C) 2019, Google LLC.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
@@ -18,11 +18,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../../src/jinclude.h"
|
||||
#include "../../../src/jpeglib.h"
|
||||
#include "../../../src/jsimd.h"
|
||||
#include "../../../src/jdct.h"
|
||||
#include "../../../src/jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
|
||||
#include <ctype.h>
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
* jchuff-neon.c - Huffman entropy encoding (64-bit Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2022, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2022, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,11 +25,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../../src/jinclude.h"
|
||||
#include "../../../src/jpeglib.h"
|
||||
#include "../../../src/jsimd.h"
|
||||
#include "../../../src/jdct.h"
|
||||
#include "../../../src/jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../align.h"
|
||||
#include "../jchuff.h"
|
||||
+7
-6
@@ -3,7 +3,8 @@
|
||||
*
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2020, 2022, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2020, 2022, 2024,
|
||||
* D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, 2022, Matthieu Darbois.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
*
|
||||
@@ -17,11 +18,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../../src/jinclude.h"
|
||||
#include "../../../src/jpeglib.h"
|
||||
#include "../../../src/jsimd.h"
|
||||
#include "../../../src/jdct.h"
|
||||
#include "../../../src/jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
|
||||
#include <ctype.h>
|
||||
Vendored
+6
-6
@@ -2,7 +2,7 @@
|
||||
* jccolor-neon.c - colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -22,11 +22,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
Vendored
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jcgray-neon.c - grayscale colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,13 +22,14 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
Vendored
+6
-6
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2022, Matthieu Darbois. All Rights Reserved.
|
||||
* Copyright (C) 2022, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2022, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,11 +23,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jcsample-neon.c - downsampling (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,13 +22,14 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
Vendored
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jdcolor-neon.c - colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,13 +22,14 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
Vendored
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jdmerge-neon.c - merged upsampling/color conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,13 +22,14 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
+7
-6
@@ -2,7 +2,7 @@
|
||||
* jdsample-neon.c - upsampling (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -22,12 +22,13 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jfdctfst-neon.c - fast integer FDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,13 +22,14 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
* jfdctint-neon.c - accurate integer FDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -22,11 +22,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jidctfst-neon.c - fast integer IDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,13 +22,14 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
* jidctint-neon.c - accurate integer IDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -22,11 +22,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
* jidctred-neon.c - reduced-size IDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -22,11 +22,11 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
Vendored
+7
-5
@@ -2,6 +2,7 @@
|
||||
* jquanti-neon.c - sample data conversion and quantization (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2024, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -21,12 +22,13 @@
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../../src/jinclude.h"
|
||||
#include "../../src/jpeglib.h"
|
||||
#include "../../src/jsimd.h"
|
||||
#include "../../src/jdct.h"
|
||||
#include "../../src/jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
+9
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2024, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
@@ -35,3 +35,11 @@
|
||||
#else
|
||||
#error "Unknown compiler"
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wdeclaration-after-statement"
|
||||
#pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
#endif
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -7,11 +7,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -7,11 +7,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -7,11 +7,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -7,11 +7,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains an SSE2 implementation for Huffman coding of one block.
|
||||
; The following code is based on jchuff.c; see jchuff.c for more details.
|
||||
+1
-5
@@ -7,11 +7,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains an SSE2 implementation of data preparation for progressive
|
||||
; Huffman encoding. See jcphuff.c for more details.
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
+1
-5
@@ -9,11 +9,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a floating-point implementation of the forward DCT
|
||||
; (Discrete Cosine Transform). The following code is based directly on
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a floating-point implementation of the forward DCT
|
||||
; (Discrete Cosine Transform). The following code is based directly on
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a fast, not so accurate integer implementation of
|
||||
; the forward DCT (Discrete Cosine Transform). The following code is
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a fast, not so accurate integer implementation of
|
||||
; the forward DCT (Discrete Cosine Transform). The following code is
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a slower but more accurate integer implementation of the
|
||||
; forward DCT (Discrete Cosine Transform). The following code is based
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a slower but more accurate integer implementation of the
|
||||
; forward DCT (Discrete Cosine Transform). The following code is based
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a slower but more accurate integer implementation of the
|
||||
; forward DCT (Discrete Cosine Transform). The following code is based
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a floating-point implementation of the inverse DCT
|
||||
; (Discrete Cosine Transform). The following code is based directly on
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a floating-point implementation of the inverse DCT
|
||||
; (Discrete Cosine Transform). The following code is based directly on
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a floating-point implementation of the inverse DCT
|
||||
; (Discrete Cosine Transform). The following code is based directly on
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a fast, not so accurate integer implementation of
|
||||
; the inverse DCT (Discrete Cosine Transform). The following code is
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a fast, not so accurate integer implementation of
|
||||
; the inverse DCT (Discrete Cosine Transform). The following code is
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a slower but more accurate integer implementation of the
|
||||
; inverse DCT (Discrete Cosine Transform). The following code is based
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a slower but more accurate integer implementation of the
|
||||
; inverse DCT (Discrete Cosine Transform). The following code is based
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains a slower but more accurate integer implementation of the
|
||||
; inverse DCT (Discrete Cosine Transform). The following code is based
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains inverse-DCT routines that produce reduced-size
|
||||
; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
|
||||
+1
-5
@@ -8,11 +8,7 @@
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
; This file should be assembled with NASM (Netwide Assembler) or Yasm.
|
||||
;
|
||||
; This file contains inverse-DCT routines that produce reduced-size
|
||||
; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user