From 8f4017ddea0c03b0418781f8a2f9e9a96a9dc841 Mon Sep 17 00:00:00 2001 From: Michael Platings Date: Fri, 2 Feb 2024 11:33:32 +0000 Subject: [PATCH 1/3] Move nodiscard declaration to error type --- adapters/opencv/intrinsiccv_hal.cpp | 16 +- intrinsiccv/include/ctypes.h | 4 +- intrinsiccv/include/intrinsiccv.h | 222 ++++++++++-------- intrinsiccv/src/conversions/merge_neon.cpp | 21 +- intrinsiccv/src/conversions/split_neon.cpp | 21 +- .../src/filters/gaussian_blur_neon.cpp | 12 +- test/api/test_rgb_and_gray.cpp | 10 +- test/api/test_yuv_to_rgb.cpp | 8 +- 8 files changed, 167 insertions(+), 147 deletions(-) diff --git a/adapters/opencv/intrinsiccv_hal.cpp b/adapters/opencv/intrinsiccv_hal.cpp index 8881de16a..a8fb9db58 100644 --- a/adapters/opencv/intrinsiccv_hal.cpp +++ b/adapters/opencv/intrinsiccv_hal.cpp @@ -572,9 +572,10 @@ int transpose(const uchar *src_data, size_t src_step, uchar *dst_data, } template -INTRINSICCV_NODISCARD intrinsiccv_error_t call_min_max( - FunctionType min_max_func, const uchar *src_data, size_t src_stride, - int width, int height, double *min_value, double *max_value) { +intrinsiccv_error_t call_min_max(FunctionType min_max_func, + const uchar *src_data, size_t src_stride, + int width, int height, double *min_value, + double *max_value) { T tmp_min_value, tmp_max_value; T *p_min_value = min_value ? &tmp_min_value : nullptr; T *p_max_value = max_value ? &tmp_max_value : nullptr; @@ -592,10 +593,11 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t call_min_max( } template -INTRINSICCV_NODISCARD intrinsiccv_error_t -call_min_max_loc(FunctionType min_max_loc_func, const uchar *src_data, - size_t src_stride, int width, int height, double *min_value, - double *max_value, int *min_index, int *max_index) { +intrinsiccv_error_t call_min_max_loc(FunctionType min_max_loc_func, + const uchar *src_data, size_t src_stride, + int width, int height, double *min_value, + double *max_value, int *min_index, + int *max_index) { size_t tmp_min_offset, tmp_max_offset; size_t *p_min_offset = (min_value || min_index) ? &tmp_min_offset : nullptr; size_t *p_max_offset = (max_value || max_index) ? &tmp_max_offset : nullptr; diff --git a/intrinsiccv/include/ctypes.h b/intrinsiccv/include/ctypes.h index 5713bc177..428bb1315 100644 --- a/intrinsiccv/include/ctypes.h +++ b/intrinsiccv/include/ctypes.h @@ -13,7 +13,9 @@ #include "stddef.h" #endif // __cplusplus -typedef enum { +#include + +typedef enum INTRINSICCV_NODISCARD { /// Success. INTRINSICCV_OK = 0, /// Requested operation is not implemented. diff --git a/intrinsiccv/include/intrinsiccv.h b/intrinsiccv/include/intrinsiccv.h index d987ce827..441489451 100644 --- a/intrinsiccv/include/intrinsiccv.h +++ b/intrinsiccv/include/intrinsiccv.h @@ -24,17 +24,16 @@ extern "C" { #endif // __cplusplus -#define INTRINSICCV_BINARY_OP(name, type) \ - INTRINSICCV_NODISCARD 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) - -#define INTRINSICCV_BINARY_OP_SCALE(name, type, scaletype) \ - INTRINSICCV_NODISCARD 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(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) + +#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) /// Adds the values of the corresponding elements in `src_a` and `src_b`, and /// puts the result into `dst`. @@ -206,9 +205,10 @@ INTRINSICCV_BINARY_OP_SCALE(intrinsiccv_add_abs_with_threshold, int16_t, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts a grayscale image to RGBA. All channels are 8-bit wide. /// @@ -228,9 +228,10 @@ intrinsiccv_gray_to_rgb_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an RGB image to BGR. All channels are 8-bit wide. /// @@ -250,9 +251,10 @@ intrinsiccv_gray_to_rgba_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Copies a source RBG image to destination buffer. /// All channels are 8-bit wide. @@ -268,9 +270,10 @@ intrinsiccv_rgb_to_bgr_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an RGBA image to BGRA. All channels are 8-bit wide. /// @@ -290,9 +293,10 @@ intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Copies a source RBGA image to destination buffer. /// All channels are 8-bit wide. @@ -308,9 +312,10 @@ intrinsiccv_rgba_to_bgra_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an RGB image to BGRA. All channels are 8-bit wide. /// @@ -331,9 +336,10 @@ intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an RGB image to RGBA. All channels are 8-bit wide. /// @@ -354,9 +360,10 @@ intrinsiccv_rgb_to_bgra_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an RGBA image to BGR. All channels are 8-bit wide. /// @@ -377,9 +384,10 @@ intrinsiccv_rgb_to_rgba_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an RGBA image to RGB. All channels are 8-bit wide. /// @@ -400,9 +408,10 @@ intrinsiccv_rgba_to_bgr_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param width Number of elements in a row. /// @param height Number of rows in the data. /// -INTRINSICCV_NODISCARD 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_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); /// Converts an NV12 or NV21 YUV image to RGB. All channels are 8-bit wide. /// @@ -433,7 +442,7 @@ intrinsiccv_rgba_to_rgb_u8(const uint8_t *src, size_t src_stride, uint8_t *dst, /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgb_u8( +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); @@ -467,7 +476,7 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgb_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgr_u8( +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); @@ -500,7 +509,7 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgr_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgba_u8( +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); @@ -533,7 +542,7 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgba_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgra_u8( +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); @@ -556,21 +565,21 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgra_u8( /// compared to. /// @param value The value that the larger elements are set to. /// -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_threshold_binary_u8( +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_NODISCARD intrinsiccv_error_t intrinsiccv_morphology_create( +intrinsiccv_error_t intrinsiccv_morphology_create( intrinsiccv_morphology_params_t *params, intrinsiccv_rectangle_t image); -INTRINSICCV_NODISCARD intrinsiccv_error_t -intrinsiccv_morphology_release(intrinsiccv_morphology_params_t *params); +intrinsiccv_error_t intrinsiccv_morphology_release( + intrinsiccv_morphology_params_t *params); -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_dilate_u8( +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, const intrinsiccv_morphology_params_t *params); -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_erode_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, const intrinsiccv_morphology_params_t *params); @@ -584,41 +593,42 @@ INTRINSICCV_NODISCARD 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_NODISCARD 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_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, + size_t src_stride, + size_t width, size_t height, + size_t *count); -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_resize_to_quarter_u8( +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_NODISCARD intrinsiccv_error_t intrinsiccv_sobel_3x3_vertical_s16_u8( +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 channel); -INTRINSICCV_NODISCARD 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 channel); +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 channel); -INTRINSICCV_NODISCARD 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_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_NODISCARD intrinsiccv_error_t intrinsiccv_filter_create( +intrinsiccv_error_t intrinsiccv_filter_create( intrinsiccv_filter_params_t *params, intrinsiccv_rectangle_t image); -INTRINSICCV_NODISCARD intrinsiccv_error_t -intrinsiccv_filter_release(intrinsiccv_filter_params_t *params); +intrinsiccv_error_t intrinsiccv_filter_release( + intrinsiccv_filter_params_t *params); -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_gaussian_blur_3x3_u8( +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, const intrinsiccv_filter_params_t *params); -INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_gaussian_blur_5x5_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, @@ -645,14 +655,16 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_gaussian_blur_5x5_u8( /// @param channels Number of channels in the data. /// @param element_size Size of one element in bytes. /// -INTRINSICCV_NODISCARD 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_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_NODISCARD 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_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); /// Merges separate 1-channel source streams to one multi channel stream. /// @@ -675,9 +687,11 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_transpose( /// @param channels Number of channels in the destination data. /// @param element_size Size of one element in bytes. /// -INTRINSICCV_NODISCARD 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_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); /// Calculates minimum and maximum element value across the source data. /// @@ -692,25 +706,30 @@ INTRINSICCV_NODISCARD intrinsiccv_error_t intrinsiccv_merge( /// @param max_value Pointer to save result maximum value to, or nullptr if /// maximum is not to be calculated. /// -INTRINSICCV_NODISCARD 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_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); /// @copydoc intrinsiccv_min_max_u8 -INTRINSICCV_NODISCARD 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_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); /// @copydoc intrinsiccv_min_max_u8 -INTRINSICCV_NODISCARD 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_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); /// @copydoc intrinsiccv_min_max_u8 -INTRINSICCV_NODISCARD 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_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); /// @copydoc intrinsiccv_min_max_u8 -INTRINSICCV_NODISCARD 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_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); /// Finds minimum and maximum element value across the source data, /// and returns their location in the source data as offset in bytes @@ -727,13 +746,16 @@ intrinsiccv_min_max_s32(const int32_t *src, size_t src_stride, size_t width, /// @param max_offset Pointer to save result offset of maximum value to, or /// nullptr if maximum is not to be calculated. /// -INTRINSICCV_NODISCARD 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_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_NODISCARD 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_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); #ifdef __cplusplus } // extern "C" diff --git a/intrinsiccv/src/conversions/merge_neon.cpp b/intrinsiccv/src/conversions/merge_neon.cpp index b586b73c0..689ddef18 100644 --- a/intrinsiccv/src/conversions/merge_neon.cpp +++ b/intrinsiccv/src/conversions/merge_neon.cpp @@ -409,26 +409,21 @@ intrinsiccv_error_t merge(const void **srcs, const size_t *src_strides, switch (element_size) { default: case sizeof(uint8_t): - merge(srcs, src_strides, dst, dst_stride, width, height, - channels); - break; + return merge(srcs, src_strides, dst, dst_stride, width, height, + channels); case sizeof(uint16_t): - merge(srcs, src_strides, dst, dst_stride, width, height, - channels); - break; + return merge(srcs, src_strides, dst, dst_stride, width, height, + channels); case sizeof(uint32_t): - merge(srcs, src_strides, dst, dst_stride, width, height, - channels); - break; + return merge(srcs, src_strides, dst, dst_stride, width, height, + channels); case sizeof(uint64_t): - merge(srcs, src_strides, dst, dst_stride, width, height, - channels); - break; + return merge(srcs, src_strides, dst, dst_stride, width, height, + channels); } - return INTRINSICCV_OK; } } // namespace intrinsiccv::neon diff --git a/intrinsiccv/src/conversions/split_neon.cpp b/intrinsiccv/src/conversions/split_neon.cpp index bdd9620d6..82fcb8be9 100644 --- a/intrinsiccv/src/conversions/split_neon.cpp +++ b/intrinsiccv/src/conversions/split_neon.cpp @@ -299,25 +299,20 @@ intrinsiccv_error_t split(const void *src_data, size_t src_stride, switch (element_size) { default: case sizeof(uint8_t): - split(src_data, src_stride, dst_data, dst_strides, width, height, - channels); - break; + return split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); case sizeof(uint16_t): - split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); - break; + return split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); case sizeof(uint32_t): - split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); - break; + return split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); case sizeof(uint64_t): - split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); - break; + return split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); } - return INTRINSICCV_OK; } } // namespace intrinsiccv::neon diff --git a/intrinsiccv/src/filters/gaussian_blur_neon.cpp b/intrinsiccv/src/filters/gaussian_blur_neon.cpp index ce8ff4e9f..62038e762 100644 --- a/intrinsiccv/src/filters/gaussian_blur_neon.cpp +++ b/intrinsiccv/src/filters/gaussian_blur_neon.cpp @@ -169,9 +169,9 @@ intrinsiccv_error_t gaussian_blur_3x3_u8( size_t width, size_t height, size_t channels, intrinsiccv_border_type_t border_type, const intrinsiccv_filter_params_t *params) { - discrete_gaussian_blur(src, src_stride, dst, dst_stride, width, - height, channels, border_type, params); - return INTRINSICCV_OK; + return discrete_gaussian_blur(src, src_stride, dst, dst_stride, + width, height, channels, + border_type, params); } INTRINSICCV_TARGET_FN_ATTRS @@ -180,9 +180,9 @@ intrinsiccv_error_t gaussian_blur_5x5_u8( size_t width, size_t height, size_t channels, intrinsiccv_border_type_t border_type, const intrinsiccv_filter_params_t *params) { - discrete_gaussian_blur(src, src_stride, dst, dst_stride, width, - height, channels, border_type, params); - return INTRINSICCV_OK; + return discrete_gaussian_blur(src, src_stride, dst, dst_stride, + width, height, channels, + border_type, params); } } // namespace intrinsiccv::neon diff --git a/test/api/test_rgb_and_gray.cpp b/test/api/test_rgb_and_gray.cpp index c38dc9180..b0fff439f 100644 --- a/test/api/test_rgb_and_gray.cpp +++ b/test/api/test_rgb_and_gray.cpp @@ -28,9 +28,10 @@ class GrayTest final { calculate_expected(source, expected); - impl(source.data(), source.stride(), actual.data(), actual.stride(), - logical_width, actual.height()); + auto err = impl(source.data(), source.stride(), actual.data(), + actual.stride(), logical_width, actual.height()); + ASSERT_EQ(INTRINSICCV_OK, err); EXPECT_EQ_ARRAY2D(actual, expected); } @@ -79,9 +80,10 @@ class ColourTest final { calculate_expected(source, expected); - impl(source.data(), source.stride(), actual.data(), actual.stride(), - logical_width, actual.height()); + auto err = impl(source.data(), source.stride(), actual.data(), + actual.stride(), logical_width, actual.height()); + ASSERT_EQ(INTRINSICCV_OK, err); EXPECT_EQ_ARRAY2D(actual, expected); } diff --git a/test/api/test_yuv_to_rgb.cpp b/test/api/test_yuv_to_rgb.cpp index d0c14332e..ac0c31f53 100644 --- a/test/api/test_yuv_to_rgb.cpp +++ b/test/api/test_yuv_to_rgb.cpp @@ -55,10 +55,12 @@ class YuvTest final { test::Array2D actual{logical_width * channel_number_, input_y.height(), padding}; - impl(input_y.data(), input_y.stride(), input_uv.data(), input_uv.stride(), - actual.data(), actual.stride(), expected.width() / channel_number_, - expected.height(), is_nv21); + auto err = + impl(input_y.data(), input_y.stride(), input_uv.data(), + input_uv.stride(), actual.data(), actual.stride(), + expected.width() / channel_number_, expected.height(), is_nv21); + ASSERT_EQ(INTRINSICCV_OK, err); EXPECT_EQ_ARRAY2D(expected, actual); } -- GitLab From e397c0ab64e83008e0afbc2ea5e037ccfc49ecd7 Mon Sep 17 00:00:00 2001 From: Michael Platings Date: Fri, 2 Feb 2024 12:03:20 +0000 Subject: [PATCH 2/3] Remove unnecessary trap All the code that uses RowsOverUniquePtr already checks for successful allocation. --- intrinsiccv/include/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intrinsiccv/include/types.h b/intrinsiccv/include/types.h index 799a976ad..242f379f9 100644 --- a/intrinsiccv/include/types.h +++ b/intrinsiccv/include/types.h @@ -656,8 +656,8 @@ class RowsOverUniquePtr { : rect_{get_rectangle(rect, margin)}, data_{std::unique_ptr(new(std::nothrow) T[rect_.area()])} { if (!data_) { - // FIXME: add error handling - __builtin_trap(); + // Code that uses this class is required to check that data() is valid. + return; } rows_ = Rows{&data_[0], rect_.width() * sizeof(T)}; -- GitLab From 622655779f5c12c09607b26e02dd34c6f3b3f435 Mon Sep 17 00:00:00 2001 From: Michael Platings Date: Fri, 2 Feb 2024 11:19:10 +0000 Subject: [PATCH 3/3] Error handling for not-implemented cases --- adapters/opencv/intrinsiccv_hal.cpp | 13 ++++- .../src/arithmetics/transpose_neon.cpp | 3 +- intrinsiccv/src/conversions/merge_neon.cpp | 8 ++- intrinsiccv/src/conversions/split_neon.cpp | 6 +- test/api/test_merge.cpp | 54 ++++++++++++------ test/api/test_split.cpp | 55 +++++++++++++------ 6 files changed, 97 insertions(+), 42 deletions(-) diff --git a/adapters/opencv/intrinsiccv_hal.cpp b/adapters/opencv/intrinsiccv_hal.cpp index a8fb9db58..8918201d9 100644 --- a/adapters/opencv/intrinsiccv_hal.cpp +++ b/adapters/opencv/intrinsiccv_hal.cpp @@ -49,7 +49,7 @@ static size_t get_type_size(int depth) { case CV_32S: return 4; default: - __builtin_trap(); + return SIZE_MAX; } } @@ -294,7 +294,11 @@ int gaussian_blur(const uchar *src_data, size_t src_step, uchar *dst_data, intrinsiccv_filter_params_t params; params.channels = cn; - params.type_size = get_type_size(depth) * 2UL /* widening */; + params.type_size = get_type_size(depth); + if (params.type_size == SIZE_MAX) { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + params.type_size *= 2; /* widening */ intrinsiccv_rectangle_t image = { .width = static_cast(width), @@ -379,9 +383,12 @@ int morphology_init(cvhalFilter2D **context, int operation, int src_type, params->channels = (src_type >> CV_CN_SHIFT) + 1; params->iterations = static_castiterations)>(iterations); params->type_size = get_type_size(CV_MAT_DEPTH(src_type)); + if (SIZE_MAX == params->type_size) { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } if (from_opencv(border_type, params->border_type)) { - return CV_HAL_ERROR_UNKNOWN; + return CV_HAL_ERROR_NOT_IMPLEMENTED; } if (params->border_type == diff --git a/intrinsiccv/src/arithmetics/transpose_neon.cpp b/intrinsiccv/src/arithmetics/transpose_neon.cpp index 5dfc86917..55394649f 100644 --- a/intrinsiccv/src/arithmetics/transpose_neon.cpp +++ b/intrinsiccv/src/arithmetics/transpose_neon.cpp @@ -226,7 +226,6 @@ intrinsiccv_error_t transpose(const void *src, size_t src_stride, void *dst, } switch (element_size) { - default: case sizeof(uint8_t): return transpose(src, src_stride, dst, dst_stride, src_width, src_height, inplace); @@ -239,6 +238,8 @@ intrinsiccv_error_t transpose(const void *src, size_t src_stride, void *dst, case sizeof(uint64_t): return transpose(src, src_stride, dst, dst_stride, src_width, src_height, inplace); + default: + return INTRINSICCV_ERROR_NOT_IMPLEMENTED; } } diff --git a/intrinsiccv/src/conversions/merge_neon.cpp b/intrinsiccv/src/conversions/merge_neon.cpp index 689ddef18..83bdaeffc 100644 --- a/intrinsiccv/src/conversions/merge_neon.cpp +++ b/intrinsiccv/src/conversions/merge_neon.cpp @@ -377,7 +377,6 @@ intrinsiccv_error_t merge(const void **srcs, const size_t *src_strides, Rows dst_rows{dst, dst_stride, channels}; switch (channels) { - default: case 2: { Merge2 operation; apply_operation_by_rows(operation, rect, src_a_rows, src_b_rows, @@ -398,6 +397,9 @@ intrinsiccv_error_t merge(const void **srcs, const size_t *src_strides, apply_operation_by_rows(operation, rect, src_a_rows, src_b_rows, src_c_rows, src_d_rows, dst_rows); } break; + + default: + return INTRINSICCV_ERROR_NOT_IMPLEMENTED; } return INTRINSICCV_OK; } @@ -407,7 +409,6 @@ intrinsiccv_error_t 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) { switch (element_size) { - default: case sizeof(uint8_t): return merge(srcs, src_strides, dst, dst_stride, width, height, channels); @@ -423,6 +424,9 @@ intrinsiccv_error_t merge(const void **srcs, const size_t *src_strides, case sizeof(uint64_t): return merge(srcs, src_strides, dst, dst_stride, width, height, channels); + + default: + return INTRINSICCV_ERROR_NOT_IMPLEMENTED; } } diff --git a/intrinsiccv/src/conversions/split_neon.cpp b/intrinsiccv/src/conversions/split_neon.cpp index 82fcb8be9..b1ff1b827 100644 --- a/intrinsiccv/src/conversions/split_neon.cpp +++ b/intrinsiccv/src/conversions/split_neon.cpp @@ -286,7 +286,7 @@ intrinsiccv_error_t split(const void *src_data, const size_t src_stride, dst_rows2, dst_rows3); } break; default: - __builtin_trap(); + return INTRINSICCV_ERROR_NOT_IMPLEMENTED; } return INTRINSICCV_OK; } @@ -297,7 +297,6 @@ intrinsiccv_error_t split(const void *src_data, size_t src_stride, size_t width, size_t height, size_t channels, size_t element_size) { switch (element_size) { - default: case sizeof(uint8_t): return split(src_data, src_stride, dst_data, dst_strides, width, height, channels); @@ -313,6 +312,9 @@ intrinsiccv_error_t split(const void *src_data, size_t src_stride, case sizeof(uint64_t): return split(src_data, src_stride, dst_data, dst_strides, width, height, channels); + + default: + return INTRINSICCV_ERROR_NOT_IMPLEMENTED; } } } // namespace intrinsiccv::neon diff --git a/test/api/test_merge.cpp b/test/api/test_merge.cpp index 088c7d7fa..4e2dd1e3c 100644 --- a/test/api/test_merge.cpp +++ b/test/api/test_merge.cpp @@ -91,35 +91,55 @@ class MergeTest final { size_t padding_{0}; }; -template -class Merge2 : public testing::Test {}; +template +static void test_not_implemented( + intrinsiccv_error_t expected = INTRINSICCV_ERROR_NOT_IMPLEMENTED) { + const size_t width = 1, height = 1; + ElementType src_arrays[kChannels][width * height] = {{234}}; + ElementType dst[kChannels * width * height] = {123}; + size_t src_strides[kChannels]; + const void* srcs[kChannels]; + for (int i = 0; i < kChannels; ++i) { + srcs[i] = src_arrays[i]; + src_strides[i] = width * sizeof(ElementType); + } + size_t dst_stride = kChannels * width * sizeof(ElementType); -using ElementTypes = ::testing::Types; -TYPED_TEST_SUITE(Merge2, ElementTypes); + ASSERT_EQ(expected, + intrinsiccv_merge(srcs, src_strides, dst, dst_stride, width, height, + kChannels, sizeof(ElementType))); -TYPED_TEST(Merge2, API) { - MergeTest().test(); - MergeTest().with_padding(test::Options::vector_length()).test(); + // Destination should not be modified. + EXPECT_EQ(123, dst[0]); } template -class Merge3 : public testing::Test {}; +class Merge : public testing::Test {}; using ElementTypes = ::testing::Types; -TYPED_TEST_SUITE(Merge3, ElementTypes); +TYPED_TEST_SUITE(Merge, ElementTypes); + +TYPED_TEST(Merge, TwoChannels) { + MergeTest().test(); + MergeTest().with_padding(test::Options::vector_length()).test(); +} -TYPED_TEST(Merge3, API) { +TYPED_TEST(Merge, ThreeChannels) { MergeTest().test(); MergeTest().with_padding(test::Options::vector_length()).test(); } -template -class Merge4 : public testing::Test {}; - -using ElementTypes = ::testing::Types; -TYPED_TEST_SUITE(Merge4, ElementTypes); - -TYPED_TEST(Merge4, API) { +TYPED_TEST(Merge, FourChannels) { MergeTest().test(); MergeTest().with_padding(test::Options::vector_length()).test(); } + +TYPED_TEST(Merge, OneChannelNotImplemented) { + test_not_implemented(); +} + +TYPED_TEST(Merge, FiveChannelsNotImplemented) { + test_not_implemented(); +} + +TEST(Merge128, NotImplemented) { test_not_implemented<__uint128_t, 2>(); } diff --git a/test/api/test_split.cpp b/test/api/test_split.cpp index a0f23cd8f..652bb3d65 100644 --- a/test/api/test_split.cpp +++ b/test/api/test_split.cpp @@ -89,35 +89,56 @@ class SplitTest final { size_t padding_{0}; }; -template -class Split2 : public testing::Test {}; +template +static void test_not_implemented( + intrinsiccv_error_t expected = INTRINSICCV_ERROR_NOT_IMPLEMENTED) { + const size_t width = 1, height = 1; + + ElementType src_data[kChannels * width * height] = {234}; + size_t src_stride = kChannels * width * sizeof(ElementType); + ElementType dst_arrays[kChannels][width * height] = {{123}}; + void* dst_data[kChannels]; + size_t dst_strides[kChannels]; + for (int i = 0; i < kChannels; ++i) { + dst_data[i] = dst_arrays[i]; + dst_strides[i] = width * sizeof(ElementType); + } -using ElementTypes = ::testing::Types; -TYPED_TEST_SUITE(Split2, ElementTypes); + ASSERT_EQ(expected, + intrinsiccv_split(src_data, src_stride, dst_data, dst_strides, + width, height, kChannels, sizeof(ElementType))); -TYPED_TEST(Split2, API) { - SplitTest().test(); - SplitTest().with_padding(test::Options::vector_length()).test(); + // Destination should not be modified. + EXPECT_EQ(123, dst_arrays[0][0]); } template -class Split3 : public testing::Test {}; +class Split : public testing::Test {}; using ElementTypes = ::testing::Types; -TYPED_TEST_SUITE(Split3, ElementTypes); +TYPED_TEST_SUITE(Split, ElementTypes); + +TYPED_TEST(Split, TwoChannels) { + SplitTest().test(); + SplitTest().with_padding(test::Options::vector_length()).test(); +} -TYPED_TEST(Split3, API) { +TYPED_TEST(Split, ThreeChannels) { SplitTest().test(); SplitTest().with_padding(test::Options::vector_length()).test(); } -template -class Split4 : public testing::Test {}; - -using ElementTypes = ::testing::Types; -TYPED_TEST_SUITE(Split4, ElementTypes); - -TYPED_TEST(Split4, API) { +TYPED_TEST(Split, FourChannels) { SplitTest().test(); SplitTest().with_padding(test::Options::vector_length()).test(); } + +TYPED_TEST(Split, OneChannelNotImplemented) { + test_not_implemented(); +} + +TYPED_TEST(Split, FiveChannelsNotImplemented) { + test_not_implemented(); +} + +TEST(Split128, NotImplemented) { test_not_implemented<__uint128_t, 2>(); } -- GitLab