diff --git a/Doxyfile b/Doxyfile index f6f966ddc07de479e9d8d4b9e8aa0cbb1e29c96c..4746ceae870271940b31e04e0e7e0cdcbff127cc 100644 --- a/Doxyfile +++ b/Doxyfile @@ -17,5 +17,6 @@ HTML_TIMESTAMP = YES GENERATE_LATEX = NO MACRO_EXPANSION = YES DIRECTORY_GRAPH = NO -PREDEFINED = __aarch64__= +PREDEFINED = __aarch64__= \ + DOXYGEN TYPEDEF_HIDES_STRUCT = YES diff --git a/adapters/opencv/intrinsiccv_hal.cpp b/adapters/opencv/intrinsiccv_hal.cpp index 4e2f2af04a4472ad73c322618dd6b1cb10c23648..dacc42e411bee8d60a2209c3016a35c5d3cd15ad 100644 --- a/adapters/opencv/intrinsiccv_hal.cpp +++ b/adapters/opencv/intrinsiccv_hal.cpp @@ -251,7 +251,7 @@ int gaussian_blur(const uchar *src_data, size_t src_step, uchar *dst_data, return CV_HAL_ERROR_NOT_IMPLEMENTED; } - decltype(intrinsiccv_gaussian_blur_3x3_u8) *impl{nullptr}; + decltype(intrinsiccv_gaussian_blur_3x3_u8) impl{nullptr}; if ((ksize_width == 3) && (ksize_height == 3) && (width >= 3) && (height >= 3)) { impl = intrinsiccv_gaussian_blur_3x3_u8; @@ -289,7 +289,7 @@ int gaussian_blur(const uchar *src_data, size_t src_step, uchar *dst_data, struct MorphologyParams { intrinsiccv_morphology_context_t *context; - decltype(intrinsiccv_dilate_u8) *impl; + decltype(intrinsiccv_dilate_u8) impl; }; int morphology_init(cvhalFilter2D **cvcontext, int operation, int src_type, diff --git a/intrinsiccv/CMakeLists.txt b/intrinsiccv/CMakeLists.txt index 188b61fa3d2a4d551a4d4aaeb3be2758b446769e..c0caf9a7b9c86aa2713a196c4861ff7fd056cde6 100644 --- a/intrinsiccv/CMakeLists.txt +++ b/intrinsiccv/CMakeLists.txt @@ -8,9 +8,15 @@ project("IntrinsicCV") include(CheckCXXCompilerFlag) -option(INTRINSICCV_ENABLE_SVE2 "Explicitly enables or disables SVE2 code paths for all supported algorithms" OFF) -option(INTRINSICCV_ENABLE_SVE2_SELECTIVELY "Explicitly enables or disables SVE2 code paths for selected algorithms" ON) -option(INTRINSICCV_ENABLE_SME2 "Explicitly enables or disables SME2 code paths for all supported algorithms" ON) +if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Android)$") + option(INTRINSICCV_ENABLE_SVE2 "Explicitly enables or disables SVE2 code paths for all supported algorithms" OFF) + option(INTRINSICCV_ENABLE_SVE2_SELECTIVELY "Explicitly enables or disables SVE2 code paths for selected algorithms" ON) + option(INTRINSICCV_ENABLE_SME2 "Explicitly enables or disables SME2 code paths for all supported algorithms" ON) +else() + set(INTRINSICCV_ENABLE_SVE2 OFF) + set(INTRINSICCV_ENABLE_SVE2_SELECTIVELY OFF) + set(INTRINSICCV_ENABLE_SME2 OFF) +endif() option(INTRINSICCV_CHECK_BANNED_FUNCTIONS "Check source for deprecated or obsolescent functions" OFF) option(INTRINSICCV_ASSUME_128BIT_SVE2 "Internal - If turned ON 128-bit SVE2 vector length is assumed" OFF) option(INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE "Internal - If turned ON interleaving loads and stores are preferred instead of continuous loads and stores" OFF) diff --git a/intrinsiccv/include/intrinsiccv/config.h.in b/intrinsiccv/include/intrinsiccv/config.h.in index a92ddfc1a6fa460b8b41a1704f9b5dfd24e52739..7100497129d38ff6c81ff43599344770b328173a 100644 --- a/intrinsiccv/include/intrinsiccv/config.h.in +++ b/intrinsiccv/include/intrinsiccv/config.h.in @@ -53,18 +53,19 @@ #define INTRINSICCV_STREAMING_COMPATIBLE #endif -#define INTRINSICCV_ATTR_IFUNC(resolver) __attribute__((ifunc(resolver))) +#ifdef __linux__ #define INTRINSICCV_ATTR_SECTION(section_to_use) \ __attribute__((section(section_to_use))) +#else +#define INTRINSICCV_ATTR_SECTION(x) +#endif + #define INTRINSICCV_ATTR_NOINLINE __attribute__((noinline)) #define INTRINSICCV_ATTR_ALIGNED(alignment) __attribute__((aligned(alignment))) #define INTRINSICCV_LIKELY(cond) __builtin_expect((cond), 1) #define INTRINSICCV_UNLIKELY(cond) __builtin_expect((cond), 0) -#define INTRINSICCV_IFUNC_RESOLVER \ - INTRINSICCV_ATTR_SECTION(".text.ifunc_resolvers") - #ifdef __clang__ #define INTRINSICCV_FORCE_LOOP_UNROLL _Pragma("clang loop unroll(full)") #else diff --git a/intrinsiccv/include/intrinsiccv/dispatch.h b/intrinsiccv/include/intrinsiccv/dispatch.h index 6c5d91675d870463b75b680815bd35824bd7779f..5ccea8fbf139f3fe9c6df719ee602aa3ead86e37 100644 --- a/intrinsiccv/include/intrinsiccv/dispatch.h +++ b/intrinsiccv/include/intrinsiccv/dispatch.h @@ -5,11 +5,14 @@ #ifndef INTRINSICCV_DISPATCH_H #define INTRINSICCV_DISPATCH_H +#if INTRINSICCV_HAVE_SVE2 || INTRINSICCV_HAVE_SME2 +#include +#endif + #include #include #include "intrinsiccv/config.h" -#include "sys/ifunc.h" namespace intrinsiccv { @@ -20,67 +23,69 @@ struct HwCaps final { HwCapTy hwcap2; }; -static inline HwCaps make_hwcaps(HwCapTy hwcap, __ifunc_arg_t *arg) { - HwCapTy hwcap2 = hwcap & _IFUNC_ARG_HWCAP ? arg->_hwcap2 : 0; - return HwCaps{hwcap, hwcap2}; -} - -static inline bool hwcaps_has_sve2(HwCaps hwcaps) { - return hwcaps.hwcap2 & (1 << 1); -} - -static inline bool hwcaps_has_sme2(HwCaps hwcaps) { - // Actually checks for SME, not SME2, but this will be changed to check for - // SME2 in future. - const int kSMEBit = 23; - return hwcaps.hwcap2 & (1UL << kSMEBit); -} - #if INTRINSICCV_ALWAYS_ENABLE_SVE2 #define INTRINSICCV_SVE2_IMPL_IF(func) func #else #define INTRINSICCV_SVE2_IMPL_IF(func) nullptr #endif +#if INTRINSICCV_HAVE_SVE2 || INTRINSICCV_HAVE_SME2 +static inline HwCaps get_hwcaps() { + return HwCaps{getauxval(AT_HWCAP), getauxval(AT_HWCAP2)}; +} + #ifdef INTRINSICCV_HAVE_SVE2 -#define INTRINSICCV_SVE2_RESOLVE_IFUNC(sve2_impl) \ +static inline bool hwcaps_has_sve2(HwCaps hwcaps) { + return hwcaps.hwcap2 & (1 << 1); +} + +#define INTRINSICCV_SVE2_RESOLVE(sve2_impl) \ if (!std::is_null_pointer_v && \ hwcaps_has_sve2(hwcaps)) { \ return sve2_impl; \ } - #else -#define INTRINSICCV_SVE2_RESOLVE_IFUNC(sve2_impl) +#define INTRINSICCV_SVE2_RESOLVE(x) #endif #ifdef INTRINSICCV_HAVE_SME2 -#define INTRINSICCV_SME2_RESOLVE_IFUNC(sme2_impl) \ +static inline bool hwcaps_has_sme2(HwCaps hwcaps) { + // Actually checks for SME, not SME2, but this will be changed to check for + // SME2 in future. + const int kSMEBit = 23; + return hwcaps.hwcap2 & (1UL << kSMEBit); +} + +#define INTRINSICCV_SME2_RESOLVE(sme2_impl) \ if (!std::is_null_pointer_v && \ hwcaps_has_sme2(hwcaps)) { \ return sme2_impl; \ } #else -#define INTRINSICCV_SME2_RESOLVE_IFUNC(sme2_impl) +#define INTRINSICCV_SME2_RESOLVE(x) +#endif + +#define INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, \ + sme2_impl) \ + static decltype(neon_impl) *api_name##_resolver() { \ + [[maybe_unused]] HwCaps hwcaps = get_hwcaps(); \ + INTRINSICCV_SME2_RESOLVE(sme2_impl); \ + INTRINSICCV_SVE2_RESOLVE(sve2_impl); \ + return neon_impl; \ + } +#else +#define INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, \ + sme2_impl) \ + static decltype(neon_impl) *api_name##_resolver() { return neon_impl; } #endif -// Creates a multiversioned C API with an ifunc resolver for it -#define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ - sme2_impl, ...) \ - typedef intrinsiccv_error_t (*api_name##_function_type)(__VA_ARGS__); \ - \ - extern "C" INTRINSICCV_IFUNC_RESOLVER api_name##_function_type \ - api_name##_ifunc_resolver(HwCapTy, __ifunc_arg_t *arg); \ - \ - extern "C" api_name##_function_type api_name##_ifunc_resolver( \ - HwCapTy hwcap, __ifunc_arg_t *arg) { \ - [[maybe_unused]] HwCaps hwcaps = make_hwcaps(hwcap, arg); \ - INTRINSICCV_SME2_RESOLVE_IFUNC(sme2_impl); \ - INTRINSICCV_SVE2_RESOLVE_IFUNC(sve2_impl); \ - return neon_impl; \ - } \ - \ - extern "C" intrinsiccv_error_t api_name(__VA_ARGS__) \ - INTRINSICCV_ATTR_IFUNC(#api_name "_ifunc_resolver") +#define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ + sme2_impl) \ + INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, sme2_impl) \ + \ + extern "C" { \ + decltype(neon_impl) *api_name = api_name##_resolver(); \ + } } // namespace intrinsiccv diff --git a/intrinsiccv/include/intrinsiccv/intrinsiccv.h b/intrinsiccv/include/intrinsiccv/intrinsiccv.h index c691afc7c516adb99815d7c3c3732f61a1ca8864..fdf0f2af1c7c9bfd85f3981cfd8cf05f4eada390 100644 --- a/intrinsiccv/include/intrinsiccv/intrinsiccv.h +++ b/intrinsiccv/include/intrinsiccv/intrinsiccv.h @@ -48,16 +48,25 @@ extern "C" { #endif // __cplusplus -#define INTRINSICCV_BINARY_OP(name, type) \ - intrinsiccv_error_t name(const type *src_a, size_t src_a_stride, \ - const type *src_b, size_t src_b_stride, type *dst, \ - size_t dst_stride, size_t width, size_t height) +#ifdef DOXYGEN +#define INTRINSICCV_API_DECLARATION(name, ...) \ + intrinsiccv_error_t name(__VA_ARGS__) +#else +#define INTRINSICCV_API_DECLARATION(name, ...) \ + extern intrinsiccv_error_t (*name)(__VA_ARGS__) +#endif + +#define INTRINSICCV_BINARY_OP(name, type) \ + INTRINSICCV_API_DECLARATION(name, const type *src_a, size_t src_a_stride, \ + const type *src_b, size_t src_b_stride, \ + type *dst, size_t dst_stride, size_t width, \ + size_t height) -#define INTRINSICCV_BINARY_OP_SCALE(name, type, scaletype) \ - intrinsiccv_error_t name(const type *src_a, size_t src_a_stride, \ - const type *src_b, size_t src_b_stride, type *dst, \ - size_t dst_stride, size_t width, size_t height, \ - scaletype scale) +#define INTRINSICCV_BINARY_OP_SCALE(name, type, scaletype) \ + INTRINSICCV_API_DECLARATION(name, const type *src_a, size_t src_a_stride, \ + const type *src_b, size_t src_b_stride, \ + type *dst, size_t dst_stride, size_t width, \ + size_t height, scaletype scale) /// Adds the values of the corresponding elements in `src_a` and `src_b`, and /// puts the result into `dst`. @@ -255,10 +264,11 @@ INTRINSICCV_BINARY_OP_SCALE(intrinsiccv_saturating_multiply_s32, int32_t, /// @param threshold The value that the elements of the addition result /// are compared to. /// -intrinsiccv_error_t intrinsiccv_saturating_add_abs_with_threshold_s16( - const int16_t *src_a, size_t src_a_stride, const int16_t *src_b, - size_t src_b_stride, int16_t *dst, size_t dst_stride, size_t width, - size_t height, int16_t threshold); +INTRINSICCV_API_DECLARATION(intrinsiccv_saturating_add_abs_with_threshold_s16, + const int16_t *src_a, size_t src_a_stride, + const int16_t *src_b, size_t src_b_stride, + int16_t *dst, size_t dst_stride, size_t width, + size_t height, int16_t threshold); /// Converts a grayscale image to RGB. All channels are 8-bit wide. /// @@ -281,10 +291,9 @@ intrinsiccv_error_t intrinsiccv_saturating_add_abs_with_threshold_s16( /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_gray_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_gray_to_rgb_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts a grayscale image to RGBA. All channels are 8-bit wide. /// @@ -307,10 +316,9 @@ intrinsiccv_error_t intrinsiccv_gray_to_rgb_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_gray_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_gray_to_rgba_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGB image to BGR. All channels are 8-bit wide. /// @@ -333,10 +341,9 @@ intrinsiccv_error_t intrinsiccv_gray_to_rgba_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_bgr_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_bgr_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Copies a source RBG image to destination buffer. /// All channels are 8-bit wide. @@ -355,10 +362,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_bgr_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_rgb_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGBA image to BGRA. All channels are 8-bit wide. /// @@ -381,10 +387,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_bgra_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_bgra_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Copies a source RBGA image to destination buffer. /// All channels are 8-bit wide. @@ -403,10 +408,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_bgra_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_rgba_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGB image to BGRA. All channels are 8-bit wide. /// @@ -430,10 +434,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_bgra_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_bgra_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGB image to RGBA. All channels are 8-bit wide. /// @@ -457,10 +460,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_bgra_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_rgba_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGBA image to BGR. All channels are 8-bit wide. /// @@ -484,10 +486,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgba_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_bgr_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_bgr_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGBA image to RGB. All channels are 8-bit wide. /// @@ -511,10 +512,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_bgr_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_rgb_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an NV12 or NV21 YUV image to RGB. All channels are 8-bit wide. /// @@ -548,10 +548,11 @@ intrinsiccv_error_t intrinsiccv_rgba_to_rgb_u8(const uint8_t *src, /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgb_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_rgb_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Converts an NV12 or NV21 YUV image to BGR. All channels are 8-bit wide. /// @@ -585,10 +586,11 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgb_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgr_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_bgr_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Converts an NV12 or NV21 YUV image to RGBA. All channels are 8-bit wide. /// Alpha channel is set to 0xFF. @@ -621,10 +623,11 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgr_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgba_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_rgba_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Converts an NV12 or NV21 YUV image to BGRA. All channels are 8-bit wide. /// Alpha channel is set to 0xFF. @@ -657,10 +660,11 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgba_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgra_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_bgra_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Performs a comparison of each element's value in `src` with respect to a /// caller defined threshold. The strictly larger elements are set to @@ -685,9 +689,10 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgra_u8( /// compared to. /// @param value The value that the larger elements are set to. /// -intrinsiccv_error_t intrinsiccv_threshold_binary_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, uint8_t threshold, uint8_t value); +INTRINSICCV_API_DECLARATION(intrinsiccv_threshold_binary_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, uint8_t threshold, + uint8_t value); /// Creates a morphology context according to the parameters. /// @@ -769,15 +774,17 @@ intrinsiccv_error_t intrinsiccv_morphology_release( /// @param height Number of rows in the data. /// @param context Pointer to morphology context. /// -intrinsiccv_error_t intrinsiccv_dilate_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, intrinsiccv_morphology_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_dilate_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, + intrinsiccv_morphology_context_t *context); /// @copydoc intrinsiccv_dilate_u8 /// -intrinsiccv_error_t intrinsiccv_erode_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, intrinsiccv_morphology_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_erode_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, + intrinsiccv_morphology_context_t *context); /// Counts how many nonzero elements are in the source data. Number of elements /// is limited to @ref INTRINSICCV_MAX_IMAGE_PIXELS. @@ -791,10 +798,9 @@ intrinsiccv_error_t intrinsiccv_erode_u8( /// @param height Number of rows in the data. /// @param count Pointer to variable to store result. Must be non-null. /// -intrinsiccv_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, - size_t src_stride, - size_t width, size_t height, - size_t *count); +INTRINSICCV_API_DECLARATION(intrinsiccv_count_nonzeros_u8, const uint8_t *src, + size_t src_stride, size_t width, size_t height, + size_t *count); /// Resizes source data by averaging 4 elements to one. /// @@ -839,9 +845,11 @@ intrinsiccv_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, /// For odd src_height it must be either src_height / 2 /// or (src_height / 2) + 1. /// -intrinsiccv_error_t intrinsiccv_resize_to_quarter_u8( - const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height, - uint8_t *dst, size_t dst_stride, size_t dst_width, size_t dst_height); +INTRINSICCV_API_DECLARATION(intrinsiccv_resize_to_quarter_u8, + const uint8_t *src, size_t src_stride, + size_t src_width, size_t src_height, uint8_t *dst, + size_t dst_stride, size_t dst_width, + size_t dst_height); /// Calculates vertical derivative approximation with Sobel filter. /// @@ -875,9 +883,10 @@ intrinsiccv_error_t intrinsiccv_resize_to_quarter_u8( /// @param channels Number of channels in the data. Must be not more than /// @ref INTRINSICCV_MAXIMUM_CHANNEL_COUNT. /// -intrinsiccv_error_t intrinsiccv_sobel_3x3_vertical_s16_u8( - const uint8_t *src, size_t src_stride, int16_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels); +INTRINSICCV_API_DECLARATION(intrinsiccv_sobel_3x3_vertical_s16_u8, + const uint8_t *src, size_t src_stride, int16_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels); /// Calculates horizontal derivative approximation with Sobel filter. /// @@ -911,9 +920,10 @@ intrinsiccv_error_t intrinsiccv_sobel_3x3_vertical_s16_u8( /// @param channels Number of channels in the data. Must be not more than /// @ref INTRINSICCV_MAXIMUM_CHANNEL_COUNT. /// -intrinsiccv_error_t intrinsiccv_sobel_3x3_horizontal_s16_u8( - const uint8_t *src, size_t src_stride, int16_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels); +INTRINSICCV_API_DECLARATION(intrinsiccv_sobel_3x3_horizontal_s16_u8, + const uint8_t *src, size_t src_stride, int16_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels); #if INTRINSICCV_EXPERIMENTAL_FEATURE_CANNY /// Canny edge detector for uint8_t grayscale input. Output is also a uint8_t @@ -943,11 +953,10 @@ intrinsiccv_error_t intrinsiccv_sobel_3x3_horizontal_s16_u8( /// @param low_threshold Low threshold for the edge detector algorithm. /// @param high_threshold High threshold for the edge detector algorithm. /// -intrinsiccv_error_t intrinsiccv_canny_u8(const uint8_t *src, size_t src_stride, - uint8_t *dst, size_t dst_stride, - size_t width, size_t height, - double low_threshold, - double high_threshold); +INTRINSICCV_API_DECLARATION(intrinsiccv_canny_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, double low_threshold, + double high_threshold); #endif // INTRINSICCV_EXPERIMENTAL_FEATURE_CANNY /// Creates a filter context according to the parameters. @@ -1027,19 +1036,21 @@ intrinsiccv_error_t intrinsiccv_filter_release( /// @param border_type Way of handling the border. /// @param context Pointer to filter context. /// -intrinsiccv_error_t intrinsiccv_gaussian_blur_3x3_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels, - intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_gaussian_blur_3x3_u8, + const uint8_t *src, size_t src_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels, + intrinsiccv_border_type_t border_type, + intrinsiccv_filter_context_t *context); /// @copydoc intrinsiccv_gaussian_blur_3x3_u8 /// -intrinsiccv_error_t intrinsiccv_gaussian_blur_5x5_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels, - intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_gaussian_blur_5x5_u8, + const uint8_t *src, size_t src_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels, + intrinsiccv_border_type_t border_type, + intrinsiccv_filter_context_t *context); /// Splits a multi channel source stream into separate 1-channel streams. Width /// and height are the same for the source stream and for all the destination @@ -1069,11 +1080,11 @@ intrinsiccv_error_t intrinsiccv_gaussian_blur_5x5_u8( /// 4. /// @param element_size Size of one element in bytes. Must be 1, 2, 4 or 8. /// -intrinsiccv_error_t intrinsiccv_split(const void *src_data, size_t src_stride, - void **dst_data, - const size_t *dst_strides, size_t width, - size_t height, size_t channels, - size_t element_size); +INTRINSICCV_API_DECLARATION(intrinsiccv_split, const void *src_data, + size_t src_stride, void **dst_data, + const size_t *dst_strides, size_t width, + size_t height, size_t channels, + size_t element_size); /// Matrix transpose operation. /// Inplace transpose ('src == dst') is only supported for @@ -1106,10 +1117,10 @@ intrinsiccv_error_t intrinsiccv_split(const void *src_data, size_t src_stride, /// @param src_height Number of rows in the data. /// @param element_size Size of one element in bytes. Must be 1, 2, 4 or 8. /// -intrinsiccv_error_t intrinsiccv_transpose(const void *src, size_t src_stride, - void *dst, size_t dst_stride, - size_t src_width, size_t src_height, - size_t element_size); +INTRINSICCV_API_DECLARATION(intrinsiccv_transpose, const void *src, + size_t src_stride, void *dst, size_t dst_stride, + size_t src_width, size_t src_height, + size_t element_size); /// Merges separate 1-channel source streams to one multi channel stream. Width /// and height are the same for all the source streams and for the destination. @@ -1139,11 +1150,10 @@ intrinsiccv_error_t intrinsiccv_transpose(const void *src, size_t src_stride, /// 3 or 4. /// @param element_size Size of one element in bytes. Must be 1, 2, 4 or 8. /// -intrinsiccv_error_t intrinsiccv_merge(const void **srcs, - const size_t *src_strides, void *dst, - size_t dst_stride, size_t width, - size_t height, size_t channels, - size_t element_size); +INTRINSICCV_API_DECLARATION(intrinsiccv_merge, const void **srcs, + const size_t *src_strides, void *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels, size_t element_size); /// Calculates minimum and maximum element value across the source data. Number /// of elements is limited to @ref INTRINSICCV_MAX_IMAGE_PIXELS. @@ -1160,30 +1170,25 @@ intrinsiccv_error_t intrinsiccv_merge(const void **srcs, /// @param max_value Pointer to save result maximum value to, or nullptr if /// maximum is not to be calculated. /// -intrinsiccv_error_t intrinsiccv_min_max_u8(const uint8_t *src, - size_t src_stride, size_t width, - size_t height, uint8_t *min_value, - uint8_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_u8, const uint8_t *src, + size_t src_stride, size_t width, size_t height, + uint8_t *min_value, uint8_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_s8(const int8_t *src, size_t src_stride, - size_t width, size_t height, - int8_t *min_value, - int8_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_s8, const int8_t *src, + size_t src_stride, size_t width, size_t height, + int8_t *min_value, int8_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_u16(const uint16_t *src, - size_t src_stride, size_t width, - size_t height, uint16_t *min_value, - uint16_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_u16, const uint16_t *src, + size_t src_stride, size_t width, size_t height, + uint16_t *min_value, uint16_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_s16(const int16_t *src, - size_t src_stride, size_t width, - size_t height, int16_t *min_value, - int16_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_s16, const int16_t *src, + size_t src_stride, size_t width, size_t height, + int16_t *min_value, int16_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_s32(const int32_t *src, - size_t src_stride, size_t width, - size_t height, int32_t *min_value, - int32_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_s32, const int32_t *src, + size_t src_stride, size_t width, size_t height, + int32_t *min_value, int32_t *max_value); /// Finds minimum and maximum element value across the source data, /// and returns their location in the source data as offset in bytes @@ -1202,11 +1207,9 @@ intrinsiccv_error_t intrinsiccv_min_max_s32(const int32_t *src, /// @param max_offset Pointer to save result offset of maximum value to, or /// nullptr if maximum is not to be calculated. /// -intrinsiccv_error_t intrinsiccv_min_max_loc_u8(const uint8_t *src, - size_t src_stride, size_t width, - size_t height, - size_t *min_offset, - size_t *max_offset); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_loc_u8, const uint8_t *src, + size_t src_stride, size_t width, size_t height, + size_t *min_offset, size_t *max_offset); /// Multiplies the elements in `src` by `scale`, then adds `shift` to the /// result and stores it in `dst`. @@ -1230,10 +1233,10 @@ intrinsiccv_error_t intrinsiccv_min_max_loc_u8(const uint8_t *src, /// @param scale Value to multiply the input by. /// @param shift Value to add to the result. /// -intrinsiccv_error_t intrinsiccv_scale_u8(const uint8_t *src, size_t src_stride, - uint8_t *dst, size_t dst_stride, - size_t width, size_t height, - float scale, float shift); +INTRINSICCV_API_DECLARATION(intrinsiccv_scale_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, float scale, + float shift); #ifdef __cplusplus } // extern "C" diff --git a/intrinsiccv/src/analysis/count_nonzeros_neon.cpp b/intrinsiccv/src/analysis/count_nonzeros_neon.cpp index 32c3b541860955b81c33bf0a71578af14bb76aa9..f56a276182323a34d0c5b46c54c8a6ecfd9d7dba 100644 --- a/intrinsiccv/src/analysis/count_nonzeros_neon.cpp +++ b/intrinsiccv/src/analysis/count_nonzeros_neon.cpp @@ -41,15 +41,6 @@ class CountNonZeros final : public UnrollTwice { VectorType v_accumulator_; }; // end of class CountNonZeros -template -static size_t count_nonzeros_impl(Rows src, Rectangle rect) { - CountNonZeros operation; - apply_block_operation_by_rows(operation, rect, src); - return operation.result(); -} - -} // namespace neon - template INTRINSICCV_TARGET_FN_ATTRS static intrinsiccv_error_t count_nonzeros( const T *src, size_t src_stride, size_t width, size_t height, @@ -60,19 +51,20 @@ INTRINSICCV_TARGET_FN_ATTRS static intrinsiccv_error_t count_nonzeros( Rectangle rect{width, height}; Rows src_rows{src, src_stride}; - *count = neon::count_nonzeros_impl(src_rows, rect); + + CountNonZeros operation; + apply_block_operation_by_rows(operation, rect, src_rows); + *count = operation.result(); + return INTRINSICCV_OK; } +} // namespace neon + extern "C" { -INTRINSICCV_TARGET_FN_ATTRS -intrinsiccv_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, - size_t src_stride, - size_t width, size_t height, - size_t *count) { - return count_nonzeros(src, src_stride, width, height, count); -} +decltype(neon::count_nonzeros) *intrinsiccv_count_nonzeros_u8 = + neon::count_nonzeros; } // extern "C" diff --git a/intrinsiccv/src/analysis/min_max_api.cpp b/intrinsiccv/src/analysis/min_max_api.cpp index 1c79bcd179f7c9fe2d9d23859025c20043534ecb..389f7236f97434b149a88617534680963d6c3153 100644 --- a/intrinsiccv/src/analysis/min_max_api.cpp +++ b/intrinsiccv/src/analysis/min_max_api.cpp @@ -27,8 +27,7 @@ namespace sme2 {} // namespace sme2 #define INTRINSICCV_DEFINE_MINMAX_API(name, type) \ INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::min_max, \ - nullptr, nullptr, const type *, size_t, \ - size_t, size_t, type *, type *) + nullptr, nullptr) INTRINSICCV_DEFINE_MINMAX_API(intrinsiccv_min_max_u8, uint8_t); INTRINSICCV_DEFINE_MINMAX_API(intrinsiccv_min_max_s8, int8_t); @@ -38,8 +37,7 @@ INTRINSICCV_DEFINE_MINMAX_API(intrinsiccv_min_max_s32, int32_t); #define INTRINSICCV_DEFINE_MINMAXLOC_API(name, type) \ INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::min_max_loc, \ - nullptr, nullptr, const type *, size_t, \ - size_t, size_t, size_t *, size_t *) + nullptr, nullptr) INTRINSICCV_DEFINE_MINMAXLOC_API(intrinsiccv_min_max_loc_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/absdiff_api.cpp b/intrinsiccv/src/arithmetics/absdiff_api.cpp index 7f1d40ef4bb6714dd59d5f9d5e02ea22c8f96d93..4c54344e9dad44de9c4c129b7d99d3b3a79d89f2 100644 --- a/intrinsiccv/src/arithmetics/absdiff_api.cpp +++ b/intrinsiccv/src/arithmetics/absdiff_api.cpp @@ -41,8 +41,7 @@ intrinsiccv_error_t saturating_absdiff(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_absdiff, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_absdiff), \ - intrinsiccv::sme2::saturating_absdiff, const type *, size_t, \ - const type *, size_t, type *, size_t, size_t, size_t) + intrinsiccv::sme2::saturating_absdiff) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_absdiff_u8, uint8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_absdiff_s8, int8_t); diff --git a/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp b/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp index e4c24b563c627a26cd620d51e40971dfd9813bfd..2470734313a335e1010496114ac9e7d9f5d3da35 100644 --- a/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp +++ b/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp @@ -32,14 +32,12 @@ intrinsiccv_error_t saturating_add_abs_with_threshold( } // namespace sme2 -#define INTRINSICCV_DEFINE_C_API(name, type) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::saturating_add_abs_with_threshold, \ - INTRINSICCV_SVE2_IMPL_IF( \ - intrinsiccv::sve2::saturating_add_abs_with_threshold), \ - intrinsiccv::sme2::saturating_add_abs_with_threshold, \ - const type *, size_t, const type *, size_t, type *, size_t, size_t, \ - size_t, type) +#define INTRINSICCV_DEFINE_C_API(name, type) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::saturating_add_abs_with_threshold, \ + INTRINSICCV_SVE2_IMPL_IF( \ + intrinsiccv::sve2::saturating_add_abs_with_threshold), \ + intrinsiccv::sme2::saturating_add_abs_with_threshold) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_add_abs_with_threshold_s16, int16_t); diff --git a/intrinsiccv/src/arithmetics/add_api.cpp b/intrinsiccv/src/arithmetics/add_api.cpp index 9461b4e87075be297cde7c4c72652b4cf8c54dc0..a900dd0318ba596701213740191835bf2864b9ff 100644 --- a/intrinsiccv/src/arithmetics/add_api.cpp +++ b/intrinsiccv/src/arithmetics/add_api.cpp @@ -41,8 +41,7 @@ intrinsiccv_error_t saturating_add(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_add, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_add), \ - intrinsiccv::sme2::saturating_add, const type *, size_t, \ - const type *, size_t, type *, size_t, size_t, size_t) + intrinsiccv::sme2::saturating_add) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_add_s8, int8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_add_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/multiply_api.cpp b/intrinsiccv/src/arithmetics/multiply_api.cpp index 7367ff599c801f8e6a6176ece4efdb268c38989c..5514f6f7c1a120c1df53f50722c6754d41022ad7 100644 --- a/intrinsiccv/src/arithmetics/multiply_api.cpp +++ b/intrinsiccv/src/arithmetics/multiply_api.cpp @@ -42,8 +42,7 @@ intrinsiccv_error_t saturating_multiply(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_multiply, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_multiply), \ - nullptr, const type *, size_t, const type *, size_t, type *, size_t, \ - size_t, size_t, double) + nullptr) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_multiply_u8, uint8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_multiply_s8, int8_t); diff --git a/intrinsiccv/src/arithmetics/scale_api.cpp b/intrinsiccv/src/arithmetics/scale_api.cpp index 40479a5432ad69921b67ad5e55cb35772e008aa3..3241bb0f851982794d4b356c61f30f7547928a87 100644 --- a/intrinsiccv/src/arithmetics/scale_api.cpp +++ b/intrinsiccv/src/arithmetics/scale_api.cpp @@ -20,10 +20,9 @@ namespace sve2 {} // namespace sve2 namespace sme2 {} // namespace sme2 -#define INTRINSICCV_DEFINE_SCALE_API(name, type) \ - INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::scale, \ - nullptr, nullptr, const type *, size_t, \ - type *, size_t, size_t, size_t, float, float) +#define INTRINSICCV_DEFINE_SCALE_API(name, type) \ + INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::scale, \ + nullptr, nullptr) INTRINSICCV_DEFINE_SCALE_API(intrinsiccv_scale_u8, uint8_t); // INTRINSICCV_DEFINE_SCALE_API(intrinsiccv_scale_s8, int8_t); diff --git a/intrinsiccv/src/arithmetics/sub_api.cpp b/intrinsiccv/src/arithmetics/sub_api.cpp index 30fc22ad74c93df105cacaa2d609b953dbce647b..2b5fbac51dcc594bcb29b7bcc40dbf1924eee301 100644 --- a/intrinsiccv/src/arithmetics/sub_api.cpp +++ b/intrinsiccv/src/arithmetics/sub_api.cpp @@ -40,8 +40,7 @@ intrinsiccv_error_t saturating_sub(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_sub, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_sub), \ - intrinsiccv::sme2::saturating_sub, const type *, size_t, \ - const type *, size_t, type *, size_t, size_t, size_t) + intrinsiccv::sme2::saturating_sub) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_sub_s8, int8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_sub_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/threshold_api.cpp b/intrinsiccv/src/arithmetics/threshold_api.cpp index 51d36abbd43bf28f21992e50d64b831f2eddc14e..f9e962d06690ed49f22826c9d9ac80d07c34c3e9 100644 --- a/intrinsiccv/src/arithmetics/threshold_api.cpp +++ b/intrinsiccv/src/arithmetics/threshold_api.cpp @@ -28,12 +28,11 @@ intrinsiccv_error_t threshold_binary(const T *src, size_t src_stride, T *dst, size_t height, T threshold, T value); } // namespace sme2 -#define INTRINSICCV_DEFINE_C_API(name, type) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::threshold_binary, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::threshold_binary), \ - intrinsiccv::sme2::threshold_binary, const type *, size_t, type *, \ - size_t, size_t, size_t, type, type) +#define INTRINSICCV_DEFINE_C_API(name, type) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::threshold_binary, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::threshold_binary), \ + intrinsiccv::sme2::threshold_binary) INTRINSICCV_DEFINE_C_API(intrinsiccv_threshold_binary_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/transpose_api.cpp b/intrinsiccv/src/arithmetics/transpose_api.cpp index 5611c31e9bdb22558970feee366556bc9992a9ea..208e5832f69aecd628d38d609d01baf30a9b775d 100644 --- a/intrinsiccv/src/arithmetics/transpose_api.cpp +++ b/intrinsiccv/src/arithmetics/transpose_api.cpp @@ -9,8 +9,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_transpose, - intrinsiccv::neon::transpose, nullptr, nullptr, - const void *, size_t, void *, size_t, size_t, - size_t, size_t); + intrinsiccv::neon::transpose, nullptr, nullptr); } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/gray_to_rgb_api.cpp b/intrinsiccv/src/conversions/gray_to_rgb_api.cpp index 2466a0b4ae49e1d63967635cecd4c170c28053fd..f4573d8f79e3bfa36409f527584b6728430c4f88 100644 --- a/intrinsiccv/src/conversions/gray_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/gray_to_rgb_api.cpp @@ -8,12 +8,11 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ - intrinsiccv::sme2::partialname, const uint8_t *src, size_t src_stride, \ - uint8_t *dst, size_t dst_stride, size_t width, size_t height) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::partialname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_gray_to_rgb_u8, gray_to_rgb_u8); INTRINSICCV_DEFINE_C_API(intrinsiccv_gray_to_rgba_u8, gray_to_rgba_u8); diff --git a/intrinsiccv/src/conversions/merge_api.cpp b/intrinsiccv/src/conversions/merge_api.cpp index 5c66e78633ddbb666f58112bf6978e257760b078..7af61c3c06a39bfdf25d112b0d58de54ae37a97c 100644 --- a/intrinsiccv/src/conversions/merge_api.cpp +++ b/intrinsiccv/src/conversions/merge_api.cpp @@ -9,7 +9,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_merge, intrinsiccv::neon::merge, - nullptr, nullptr, const void **, const size_t *, - void *, size_t, size_t, size_t, size_t, size_t); + nullptr, nullptr); } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp index 8f2906f4d78b7fed906b9da2be4ce532317051c8..4d3ec4874b9ddc46495c0973579e4ad935d22207 100644 --- a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp @@ -9,12 +9,11 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ - intrinsiccv::sme2::partialname, const uint8_t *src, size_t src_stride, \ - uint8_t *dst, size_t dst_stride, size_t width, size_t height) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::partialname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_rgb_to_bgr_u8, rgb_to_bgr_u8); INTRINSICCV_DEFINE_C_API(intrinsiccv_rgba_to_bgra_u8, rgba_to_bgra_u8); @@ -25,10 +24,9 @@ INTRINSICCV_DEFINE_C_API(intrinsiccv_rgba_to_rgb_u8, rgba_to_rgb_u8); extern "C" { -intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height) { +static intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8_impl( + const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height) { CHECK_POINTER_AND_STRIDE(src, src_stride); CHECK_POINTER_AND_STRIDE(dst, dst_stride); CHECK_IMAGE_SIZE(width, height); @@ -40,10 +38,12 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, return INTRINSICCV_OK; } -intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height) { +decltype(intrinsiccv_rgb_to_rgb_u8_impl) *intrinsiccv_rgb_to_rgb_u8 = + intrinsiccv_rgb_to_rgb_u8_impl; + +static intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8_impl( + const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height) { CHECK_POINTER_AND_STRIDE(src, src_stride); CHECK_POINTER_AND_STRIDE(dst, dst_stride); CHECK_IMAGE_SIZE(width, height); @@ -55,6 +55,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, return INTRINSICCV_OK; } +decltype(intrinsiccv_rgba_to_rgba_u8_impl) *intrinsiccv_rgba_to_rgba_u8 = + intrinsiccv_rgba_to_rgba_u8_impl; + } // extern "C" } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/split_api.cpp b/intrinsiccv/src/conversions/split_api.cpp index 6673fba2215b1104515c8793fe09d90bb0606d7f..968667bb23770cd3ba5232ccbb685cdafbfde5cf 100644 --- a/intrinsiccv/src/conversions/split_api.cpp +++ b/intrinsiccv/src/conversions/split_api.cpp @@ -9,10 +9,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_split, intrinsiccv::neon::split, - nullptr, nullptr, const void *src_data, - size_t src_stride, void **dst_data, - const size_t *dst_strides, size_t width, - size_t height, size_t channels, - size_t element_size); + nullptr, nullptr); } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp b/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp index f315641eb3d2e2cec25f0ffd92b305a092d31547..ff6a63f614dc65fd7e5c7884520445dbb14e90fc 100644 --- a/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp @@ -8,11 +8,10 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, intrinsiccv::sve2::partialname, \ - intrinsiccv::sme2::partialname, const uint8_t *, size_t, \ - const uint8_t *, size_t, uint8_t *, size_t, size_t, size_t, bool) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::partialname, \ + intrinsiccv::sve2::partialname, \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_yuv_sp_to_rgb_u8, yuv_sp_to_rgb_u8); INTRINSICCV_DEFINE_C_API(intrinsiccv_yuv_sp_to_bgr_u8, yuv_sp_to_bgr_u8); diff --git a/intrinsiccv/src/filters/gaussian_blur_api.cpp b/intrinsiccv/src/filters/gaussian_blur_api.cpp index 7ef7e9725a5135e671379477791fc52ed64ddcd3..fd9e2b6ba2f8a066b1e0bc96308edd6644e01a1a 100644 --- a/intrinsiccv/src/filters/gaussian_blur_api.cpp +++ b/intrinsiccv/src/filters/gaussian_blur_api.cpp @@ -54,18 +54,11 @@ intrinsiccv_error_t intrinsiccv_filter_release( INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_gaussian_blur_3x3_u8, intrinsiccv::neon::gaussian_blur_3x3_u8, nullptr, - nullptr, const uint8_t *src, size_t src_stride, - uint8_t *dst, size_t dst_stride, size_t width, - size_t height, size_t channels, - intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); + nullptr); INTRINSICCV_MULTIVERSION_C_API( intrinsiccv_gaussian_blur_5x5_u8, intrinsiccv::neon::gaussian_blur_5x5_u8, INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::gaussian_blur_5x5_u8), - intrinsiccv::sme2::gaussian_blur_5x5_u8, const uint8_t *src, - size_t src_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, size_t channels, intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); + intrinsiccv::sme2::gaussian_blur_5x5_u8); } // namespace intrinsiccv diff --git a/intrinsiccv/src/filters/sobel_api.cpp b/intrinsiccv/src/filters/sobel_api.cpp index 6a74ee2cd2929c0aeb054db132165bf0527ba9f2..5092623244346dfd24d47d87bb78fbabe4885586 100644 --- a/intrinsiccv/src/filters/sobel_api.cpp +++ b/intrinsiccv/src/filters/sobel_api.cpp @@ -8,13 +8,11 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ - intrinsiccv::sme2::partialname, const uint8_t *src, size_t src_stride, \ - int16_t *dst, size_t dst_stride, size_t width, size_t height, \ - size_t channels) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::partialname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_sobel_3x3_horizontal_s16_u8, sobel_3x3_horizontal_s16_u8); diff --git a/intrinsiccv/src/morphology/morphology_api.cpp b/intrinsiccv/src/morphology/morphology_api.cpp index 19e9922f318f92be9a2477308de3963b95176688..0b351f5922544bd1aab86c0966749872129fc372 100644 --- a/intrinsiccv/src/morphology/morphology_api.cpp +++ b/intrinsiccv/src/morphology/morphology_api.cpp @@ -104,13 +104,11 @@ intrinsiccv_error_t intrinsiccv_morphology_release( } // extern "C" -#define INTRINSICCV_DEFINE_C_API(name, tname, type) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::tname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::tname), \ - intrinsiccv::sme2::tname, const type *src, size_t src_stride, \ - type *dst, size_t dst_stride, size_t width, size_t height, \ - intrinsiccv_morphology_context_t *) +#define INTRINSICCV_DEFINE_C_API(name, tname, type) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::tname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::tname), \ + intrinsiccv::sme2::tname) INTRINSICCV_DEFINE_C_API(intrinsiccv_dilate_u8, dilate, uint8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_erode_u8, erode, uint8_t); diff --git a/intrinsiccv/src/resize/resize_api.cpp b/intrinsiccv/src/resize/resize_api.cpp index 3ffad7a5c9bb3f8963a301802e247ec76b3b1a7e..461f9e95d83158d2442fe609a6619777bdef4472 100644 --- a/intrinsiccv/src/resize/resize_api.cpp +++ b/intrinsiccv/src/resize/resize_api.cpp @@ -11,8 +11,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API( intrinsiccv_resize_to_quarter_u8, intrinsiccv::neon::resize_to_quarter_u8, INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::resize_to_quarter_u8), - intrinsiccv::sme2::resize_to_quarter_u8, const uint8_t *src, - size_t src_stride, size_t src_width, size_t src_height, uint8_t *dst, - size_t dst_stride, size_t dst_width, size_t dst_height); + intrinsiccv::sme2::resize_to_quarter_u8); } // namespace intrinsiccv diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af5c11849af09eaf60dba9034143df546de81018..6de1e2a885722423711ec18484757cae591bad1e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,7 +8,10 @@ set(INTRINSICCV_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../intrinsiccv/include ${CMAKE_CURRENT_BINARY_DIR}/../intrinsiccv/include ) -set(INTRINSICCV_TEST_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(INTRINSICCV_TEST_INCLUDE_DIR + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) set(INTRINSICCV_TEST_CXX_FLAGS "-Werror" @@ -23,15 +26,26 @@ else() list(APPEND INTRINSICCV_TEST_CXX_FLAGS "-O2" "-g0") endif() -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap,malloc") +# Only perform allocation tests on Linux and Android +if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Android)$") + set(INTRINSICCV_ALLOCATION_TESTS TRUE) +endif() set(INTRINSICCV_TEST_FRAMEWORK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/framework/border.cpp ${CMAKE_CURRENT_SOURCE_DIR}/framework/test_main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/framework/utils.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/framework/wrap_malloc.cpp ) +if (INTRINSICCV_ALLOCATION_TESTS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap,malloc") + list(APPEND INTRINSICCV_TEST_FRAMEWORK_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/framework/wrap_malloc.cpp + ) +endif() + +configure_file("${CMAKE_CURRENT_LIST_DIR}/test_config.h.in" "test_config.h") + include(FetchContent) # Please update SECURITY.md if adding, removing or changing the version of third party content. FetchContent_Declare( diff --git a/test/api/test_add_abs_with_threshold.cpp b/test/api/test_add_abs_with_threshold.cpp index d7d1ea890bb743d9e3a6acc5f2af6a5152ec9f12..eae22c00b58613731c012a6e942ce2fe335bd0d5 100644 --- a/test/api/test_add_abs_with_threshold.cpp +++ b/test/api/test_add_abs_with_threshold.cpp @@ -6,6 +6,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class SaturatingAddAbsWithThresholdTestBase diff --git a/test/api/test_canny.cpp b/test/api/test_canny.cpp index 4be2534d6a61282c510c2b30af4703dd445b42dc..995846ec4007683b39e1967d9a5eb1b27ada6269 100644 --- a/test/api/test_canny.cpp +++ b/test/api/test_canny.cpp @@ -6,6 +6,7 @@ #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #if INTRINSICCV_EXPERIMENTAL_FEATURE_CANNY diff --git a/test/api/test_count_nonzeros.cpp b/test/api/test_count_nonzeros.cpp index 80abe474a6f2644fd59e8337e3e3261c3cb6af22..6ea26392fecfcde4c28506f7f47633a0d25e4e89 100644 --- a/test/api/test_count_nonzeros.cpp +++ b/test/api/test_count_nonzeros.cpp @@ -9,6 +9,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_COUNT_NONZEROS(type, suffix) \ INTRINSICCV_API(count_nonzeros, intrinsiccv_count_nonzeros_##suffix, type) diff --git a/test/api/test_gaussian_blur.cpp b/test/api/test_gaussian_blur.cpp index da70ee83e9dfaf559311687fdc28f2d9abee1a24..20c5a169955796f44b01879bed48c137e826c4f5 100644 --- a/test/api/test_gaussian_blur.cpp +++ b/test/api/test_gaussian_blur.cpp @@ -9,6 +9,7 @@ #include "framework/kernel.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_GAUSSIAN_BLUR(type, kernel_suffix, type_suffix) \ INTRINSICCV_API(gaussian_blur_##kernel_suffix, \ @@ -563,6 +564,7 @@ TYPED_TEST(GaussianBlur, InvalidContextImageSize) { EXPECT_EQ(INTRINSICCV_OK, intrinsiccv_filter_release(context)); } +#ifdef INTRINSICCV_ALLOCATION_TESTS TEST(FilterCreate, CannotAllocateFilter) { MockMallocToFail::enable(); intrinsiccv_filter_context_t *context = nullptr; @@ -571,6 +573,7 @@ TEST(FilterCreate, CannotAllocateFilter) { intrinsiccv_filter_create(&context, 1, 1, rect)); MockMallocToFail::disable(); } +#endif TEST(FilterCreate, OversizeImage) { intrinsiccv_filter_context_t *context = nullptr; diff --git a/test/api/test_merge.cpp b/test/api/test_merge.cpp index 6259929e500fd24609721a0ddaf9f4dc40711cb8..8334cc108efec942247a66b22777f7a8af49f269 100644 --- a/test/api/test_merge.cpp +++ b/test/api/test_merge.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class MergeTest final { diff --git a/test/api/test_min_max.cpp b/test/api/test_min_max.cpp index 999c448c65e84cfb19134de46388422de2b2d91e..d98e64d7f5a6c635b7b6ab37cdaa95d9dfe41474 100644 --- a/test/api/test_min_max.cpp +++ b/test/api/test_min_max.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_MIN_MAX(type, suffix) \ INTRINSICCV_API(min_max, intrinsiccv_min_max_##suffix, type) diff --git a/test/api/test_morphology.cpp b/test/api/test_morphology.cpp index 5c25c8d8b4ed64e49087b2ccb8aa3ac898196114..ce72b4389992ab57763fdc99f39e391827141d15 100644 --- a/test/api/test_morphology.cpp +++ b/test/api/test_morphology.cpp @@ -12,13 +12,14 @@ #include "framework/kernel.h" #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_PARAMS(name, impl, type, op) \ template , bool> = true> \ class name { \ public: \ - static decltype(auto) api() { return &impl; } \ + static decltype(auto) api() { return impl; } \ static decltype(auto) operation() { \ return [](type a, type b) { return op(a, b); }; \ } \ @@ -444,7 +445,8 @@ TYPED_TEST(Morphology, UnsupportedSize) { } } -TYPED_TEST(Morphology, TooBigImage) { +#ifdef INTRINSICCV_ALLOCATION_TESTS +TYPED_TEST(Morphology, CannotAllocateImage) { MockMallocToFail::enable(); intrinsiccv_morphology_context_t *context = nullptr; intrinsiccv_rectangle_t kernel{3, 3}, image{3072, 2048}; @@ -456,13 +458,21 @@ TYPED_TEST(Morphology, TooBigImage) { intrinsiccv_morphology_create(&context, kernel, anchor, border, border_values, 1, 1, sizeof(TypeParam), image)); + MockMallocToFail::disable(); +} +#endif + +TYPED_TEST(Morphology, OversizeImage) { + intrinsiccv_morphology_context_t *context = nullptr; + intrinsiccv_rectangle_t kernel{3, 1UL << 33}, image{1UL << 33, 100}; + intrinsiccv_border_type_t border = INTRINSICCV_BORDER_TYPE_REPLICATE; + intrinsiccv_border_values_t border_values{0, 0, 1, 1}; + intrinsiccv_point_t anchor{1, 1}; - intrinsiccv_rectangle_t kernel2{3, 1UL << 33}, image2{1UL << 33, 100}; EXPECT_EQ(INTRINSICCV_ERROR_RANGE, - intrinsiccv_morphology_create(&context, kernel2, anchor, border, + intrinsiccv_morphology_create(&context, kernel, anchor, border, border_values, 1, 1, - sizeof(TypeParam), image2)); - MockMallocToFail::disable(); + sizeof(TypeParam), image)); } TYPED_TEST(Morphology, InvalidAnchors) { diff --git a/test/api/test_resize_to_quarter.cpp b/test/api/test_resize_to_quarter.cpp index 7df0e8e88c3c949fc009a64408fea4a7cf3d492f..17c62b7d3a4bd6f166a445f1623223d8384a72fb 100644 --- a/test/api/test_resize_to_quarter.cpp +++ b/test/api/test_resize_to_quarter.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" class ResizeToQuarterTest final { public: diff --git a/test/api/test_rgb_and_gray.cpp b/test/api/test_rgb_and_gray.cpp index 5528589c7d55b12f939a77d329d755fa6ddcecca..491f4b79313ae771f80441679fa69d13ff24f01e 100644 --- a/test/api/test_rgb_and_gray.cpp +++ b/test/api/test_rgb_and_gray.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" class GrayTest final { public: diff --git a/test/api/test_saturating_absdiff.cpp b/test/api/test_saturating_absdiff.cpp index 0fe9daad4364dd07c548b86907f122862c22aa28..bfa85b79e5cade5bb04a10de0de0502c8b2a30dd 100644 --- a/test/api/test_saturating_absdiff.cpp +++ b/test/api/test_saturating_absdiff.cpp @@ -8,6 +8,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_SATURATING_ABSDIFF(type, suffix) \ INTRINSICCV_API(saturating_absdiff, intrinsiccv_saturating_absdiff_##suffix, \ diff --git a/test/api/test_saturating_add.cpp b/test/api/test_saturating_add.cpp index 224d56c51a79181fa7be49c1fcef770c2d415ff7..359724475f93b82e20a8170e5462a00d541ccea4 100644 --- a/test/api/test_saturating_add.cpp +++ b/test/api/test_saturating_add.cpp @@ -8,6 +8,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_SATURATING_ADD(type, suffix) \ INTRINSICCV_API(saturating_add, intrinsiccv_saturating_add_##suffix, type) diff --git a/test/api/test_saturating_multiply.cpp b/test/api/test_saturating_multiply.cpp index 321dcc1ed5fa9f961980975fe12a1eff6125db1c..86d32a2b9e87ac44f1191acc4c5cf90e40cd73dc 100644 --- a/test/api/test_saturating_multiply.cpp +++ b/test/api/test_saturating_multiply.cpp @@ -8,6 +8,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_SATURATING_MULTIPLY(type, suffix) \ INTRINSICCV_API(saturating_multiply, \ diff --git a/test/api/test_saturating_sub.cpp b/test/api/test_saturating_sub.cpp index 0c1fb80a6d8ed0b8cc787b97936c932a0fcff0f6..df3a1c339178d5a85e5102fe542df137ee48cf94 100644 --- a/test/api/test_saturating_sub.cpp +++ b/test/api/test_saturating_sub.cpp @@ -8,6 +8,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_SATURATING_SUB(type, suffix) \ INTRINSICCV_API(saturating_sub, intrinsiccv_saturating_sub_##suffix, type) diff --git a/test/api/test_scale.cpp b/test/api/test_scale.cpp index df177a1faf6c0791fb4df16e99c36571f0681889..4ecf57e7a41cc76cab4a5634331124667f2fcd05 100644 --- a/test/api/test_scale.cpp +++ b/test/api/test_scale.cpp @@ -8,6 +8,7 @@ #include "framework/generator.h" #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_SCALE(type, suffix) \ INTRINSICCV_API(scale, intrinsiccv_scale_##suffix, type) diff --git a/test/api/test_sobel.cpp b/test/api/test_sobel.cpp index 756fe9527d5199b631fd267549c3cf72ab0d68c9..ce08c4bfa5a801033fbcd2f6a193d67315e5fff3 100644 --- a/test/api/test_sobel.cpp +++ b/test/api/test_sobel.cpp @@ -10,6 +10,7 @@ #include "framework/generator.h" #include "framework/kernel.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_SOBEL_3X3_HORIZONTAL(type, suffix) \ INTRINSICCV_API(sobel_3x3_horizontal, \ @@ -223,13 +224,28 @@ TYPED_TEST(Sobel, UndersizeImage) { validWidth, underSize, 1)); } -TYPED_TEST(Sobel, OversizeImageHorizontal) { +#ifdef INTRINSICCV_ALLOCATION_TESTS +TYPED_TEST(Sobel, CannotAllocateImageHorizontal) { MockMallocToFail::enable(); using KernelTestParams = SobelKernelTestParams; typename KernelTestParams::InputType src[1] = {}; typename KernelTestParams::OutputType dst[1]; size_t validSize = 2; + EXPECT_EQ( + INTRINSICCV_ERROR_ALLOCATION, + sobel_3x3_horizontal()( + src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS / 2, + validSize, INTRINSICCV_MAXIMUM_CHANNEL_COUNT)); + MockMallocToFail::disable(); +} +#endif + +TYPED_TEST(Sobel, OversizeImageHorizontal) { + using KernelTestParams = SobelKernelTestParams; + typename KernelTestParams::InputType src[1] = {}; + typename KernelTestParams::OutputType dst[1]; + EXPECT_EQ(INTRINSICCV_ERROR_RANGE, sobel_3x3_horizontal()( src, sizeof(src), dst, sizeof(dst), @@ -238,20 +254,12 @@ TYPED_TEST(Sobel, OversizeImageHorizontal) { sobel_3x3_horizontal()( src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS, INTRINSICCV_MAX_IMAGE_PIXELS, 1)); - EXPECT_EQ( - INTRINSICCV_ERROR_ALLOCATION, - sobel_3x3_horizontal()( - src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS / 2, - validSize, INTRINSICCV_MAXIMUM_CHANNEL_COUNT)); - MockMallocToFail::disable(); } TYPED_TEST(Sobel, OversizeImageVertical) { - MockMallocToFail::enable(); using KernelTestParams = SobelKernelTestParams; typename KernelTestParams::InputType src[1] = {}; typename KernelTestParams::OutputType dst[1]; - size_t validSize = 2; EXPECT_EQ( INTRINSICCV_ERROR_RANGE, @@ -261,12 +269,6 @@ TYPED_TEST(Sobel, OversizeImageVertical) { sobel_3x3_vertical()(src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS, INTRINSICCV_MAX_IMAGE_PIXELS, 1)); - EXPECT_EQ(INTRINSICCV_ERROR_ALLOCATION, - sobel_3x3_vertical()(src, sizeof(src), dst, sizeof(dst), - INTRINSICCV_MAX_IMAGE_PIXELS / 2, - validSize, - INTRINSICCV_MAXIMUM_CHANNEL_COUNT)); - MockMallocToFail::disable(); } TYPED_TEST(Sobel, ChannelNumber) { diff --git a/test/api/test_split.cpp b/test/api/test_split.cpp index 3e750b23ed029402b16229a5a4bccae7582e818a..51c2221b2fcce3dc7274e16400182de7eae388c3 100644 --- a/test/api/test_split.cpp +++ b/test/api/test_split.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class SplitTest final { diff --git a/test/api/test_threshold_binary.cpp b/test/api/test_threshold_binary.cpp index 50205ff7516653814eb04ef5cdbed62b44bb552c..a645849ef50f38db006956e0a345b3d79b4e4ffe 100644 --- a/test/api/test_threshold_binary.cpp +++ b/test/api/test_threshold_binary.cpp @@ -6,6 +6,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_THRESHOLD_BINARY(type, suffix) \ INTRINSICCV_API(threshold_binary, intrinsiccv_threshold_binary_##suffix, type) diff --git a/test/api/test_transpose.cpp b/test/api/test_transpose.cpp index e2fe7740f105a710c2f1bfe1ff05d451ba5f5b99..ddbcc8fffa181fb935db6af078955b303446928d 100644 --- a/test/api/test_transpose.cpp +++ b/test/api/test_transpose.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/generator.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class TestTranspose final { diff --git a/test/api/test_yuv_to_rgb.cpp b/test/api/test_yuv_to_rgb.cpp index 32cbf48c3bce8fa1286cc61db3d9d65a05b985e5..b462c8ce132c1c44b2b1e5799be6b134f729d86e 100644 --- a/test/api/test_yuv_to_rgb.cpp +++ b/test/api/test_yuv_to_rgb.cpp @@ -8,6 +8,7 @@ #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" #include "intrinsiccv/utils.h" +#include "test_config.h" class YuvTest final { public: diff --git a/test/framework/utils.h b/test/framework/utils.h index 3c4a9bba5e3e4cafba9f7e6c366469b8c9d43eba..35e41e62ed92044d9d3694508472b1c8e8f6eeba 100644 --- a/test/framework/utils.h +++ b/test/framework/utils.h @@ -21,7 +21,7 @@ template , bool> = true> \ static decltype(auto) name() { \ - return &impl; \ + return impl; \ } // Generates a fatal failure with a generic message, and returns with a given diff --git a/test/test_config.h.in b/test/test_config.h.in new file mode 100644 index 0000000000000000000000000000000000000000..8b91f4d501fa132f0995782e242c5ba9d381af0b --- /dev/null +++ b/test/test_config.h.in @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef INTRINSICCV_TEST_CONFIG_H +#define INTRINSICCV_TEST_CONFIG_H + +// Main test configuration switches. + +#cmakedefine INTRINSICCV_ALLOCATION_TESTS + +#endif // INTRINSICCV_TEST_CONFIG_H