KleidiCV Coverage Report


Directory: ./
File: kleidicv/src/conversions/yuv_sp_to_rgb_sc.h
Date: 2025-09-25 14:13:34
Exec Total Coverage
Lines: 51 51 100.0%
Functions: 40 40 100.0%
Branches: 72 72 100.0%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 - 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 #ifndef KLEIDICV_YUV_SP_TO_RGB_SC_H
6 #define KLEIDICV_YUV_SP_TO_RGB_SC_H
7
8 #include "kleidicv/conversions/yuv_420_to_rgb.h"
9 #include "kleidicv/kleidicv.h"
10 #include "kleidicv/sve2.h"
11 #include "yuv420_to_rgb_sc.h"
12
13 namespace KLEIDICV_TARGET_NAMESPACE {
14
15 template <bool BGR, bool kAlpha>
16 class YUVSpToRGBxOrBGRx final : public YUV420XToRGBxOrBGRx<BGR, kAlpha> {
17 public:
18 using ContextType = Context;
19 using VecTraits = KLEIDICV_TARGET_NAMESPACE::VecTraits<uint8_t>;
20 using YUV420XToRGBxOrBGRx<BGR, kAlpha>::yuv420x_to_rgb;
21
22 1512 explicit YUVSpToRGBxOrBGRx(bool v_first) KLEIDICV_STREAMING
23 1512 : YUV420XToRGBxOrBGRx<BGR, kAlpha>(v_first) {}
24
25 // Returns the number of channels in the output image.
26 912 static constexpr size_t output_channels() KLEIDICV_STREAMING {
27 912 return kAlpha ? /* RGBA */ 4 : /* RGB */ 3;
28 }
29
30 // Processes 2 * 16 bytes (even and odd rows) of the input YUV data, and
31 // outputs 2 * 3 (or 4) * 16 bytes of RGB (or RGBA) data per loop iteration.
32 2256 void vector_path(ContextType ctx, const uint8_t *y_row_0,
33 const uint8_t *y_row_1, const uint8_t *uv_row,
34 uint8_t *rgbx_row_0,
35 uint8_t *rgbx_row_1) KLEIDICV_STREAMING {
36 2256 auto pg = ctx.predicate();
37 // Load channels: y0 and y1 are two adjacent rows.
38 2256 svuint8_t y0 = svld1(pg, y_row_0);
39 2256 svuint8_t y1 = svld1(pg, y_row_1);
40 2256 svuint8_t uv = svld1(pg, uv_row);
41 // Widen U and V to 32 bits.
42 2256 svint16_t u = svreinterpret_s16(svmovlb(uv));
43 2256 svint16_t v = svreinterpret_s16(svmovlt(uv));
44 2256 yuv420x_to_rgb(pg, y0, y1, u, v, rgbx_row_0, rgbx_row_1);
45 2256 }
46 }; // end of class YUVSpToRGBxOrBGRx<bool, bool>
47
48 using YUVSpToRGB = YUVSpToRGBxOrBGRx<false, false>;
49 using YUVSpToRGBA = YUVSpToRGBxOrBGRx<false, true>;
50 using YUVSpToBGR = YUVSpToRGBxOrBGRx<true, false>;
51 using YUVSpToBGRA = YUVSpToRGBxOrBGRx<true, true>;
52
53 template <typename OperationType, typename ScalarType>
54 1512 kleidicv_error_t yuv2rgbx_operation(
55 OperationType &operation, const ScalarType *src_y, size_t src_y_stride,
56 const ScalarType *src_uv, size_t src_uv_stride, ScalarType *dst,
57 size_t dst_stride, size_t width, size_t height) KLEIDICV_STREAMING {
58
16/16
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 348 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 348 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 348 times.
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 348 times.
✓ Branch 8 taken 30 times.
✓ Branch 9 taken 348 times.
✓ Branch 10 taken 30 times.
✓ Branch 11 taken 348 times.
✓ Branch 12 taken 30 times.
✓ Branch 13 taken 348 times.
✓ Branch 14 taken 30 times.
✓ Branch 15 taken 348 times.
1512 CHECK_POINTER_AND_STRIDE(src_y, src_y_stride, height);
59
16/16
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 318 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 318 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 318 times.
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 318 times.
✓ Branch 8 taken 30 times.
✓ Branch 9 taken 318 times.
✓ Branch 10 taken 30 times.
✓ Branch 11 taken 318 times.
✓ Branch 12 taken 30 times.
✓ Branch 13 taken 318 times.
✓ Branch 14 taken 30 times.
✓ Branch 15 taken 318 times.
1392 CHECK_POINTER_AND_STRIDE(src_uv, src_uv_stride, (height + 1) / 2);
60
16/16
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 288 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 288 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 288 times.
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 288 times.
✓ Branch 8 taken 30 times.
✓ Branch 9 taken 288 times.
✓ Branch 10 taken 30 times.
✓ Branch 11 taken 288 times.
✓ Branch 12 taken 30 times.
✓ Branch 13 taken 288 times.
✓ Branch 14 taken 30 times.
✓ Branch 15 taken 288 times.
1272 CHECK_POINTER_AND_STRIDE(dst, dst_stride, height);
61
24/24
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 258 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 228 times.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 228 times.
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 258 times.
✓ Branch 8 taken 30 times.
✓ Branch 9 taken 228 times.
✓ Branch 10 taken 60 times.
✓ Branch 11 taken 228 times.
✓ Branch 12 taken 30 times.
✓ Branch 13 taken 258 times.
✓ Branch 14 taken 30 times.
✓ Branch 15 taken 228 times.
✓ Branch 16 taken 60 times.
✓ Branch 17 taken 228 times.
✓ Branch 18 taken 30 times.
✓ Branch 19 taken 258 times.
✓ Branch 20 taken 30 times.
✓ Branch 21 taken 228 times.
✓ Branch 22 taken 60 times.
✓ Branch 23 taken 228 times.
1152 CHECK_IMAGE_SIZE(width, height);
62
63 912 Rectangle rect{width, height};
64 912 ParallelRows y_rows{src_y, src_y_stride};
65 912 Rows uv_rows{src_uv, src_uv_stride};
66 912 ParallelRows rgbx_rows{dst, dst_stride, operation.output_channels()};
67
68 912 ForwardingOperation forwarding_operation{operation};
69 912 OperationAdapter operation_adapter{forwarding_operation};
70 912 RemainingPathAdapter remaining_path_adapter{operation_adapter};
71 912 OperationContextAdapter context_adapter{remaining_path_adapter};
72 912 ParallelRowsAdapter parallel_rows_adapter{context_adapter};
73 912 RowBasedOperation row_based_operation{parallel_rows_adapter};
74 912 zip_parallel_rows(row_based_operation, rect, y_rows, uv_rows, rgbx_rows);
75 912 return KLEIDICV_OK;
76 1512 }
77
78 KLEIDICV_TARGET_FN_ATTRS
79 378 static kleidicv_error_t yuv_sp_to_rgb_u8_sc(
80 const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv,
81 size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width,
82 size_t height, bool is_nv21) KLEIDICV_STREAMING {
83 378 YUVSpToRGB operation{is_nv21};
84 1134 return yuv2rgbx_operation(operation, src_y, src_y_stride, src_uv,
85 378 src_uv_stride, dst, dst_stride, width, height);
86 378 }
87
88 KLEIDICV_TARGET_FN_ATTRS
89 378 static kleidicv_error_t yuv_sp_to_rgba_u8_sc(
90 const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv,
91 size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width,
92 size_t height, bool is_nv21) KLEIDICV_STREAMING {
93 378 YUVSpToRGBA operation{is_nv21};
94 1134 return yuv2rgbx_operation(operation, src_y, src_y_stride, src_uv,
95 378 src_uv_stride, dst, dst_stride, width, height);
96 378 }
97
98 KLEIDICV_TARGET_FN_ATTRS
99 378 static kleidicv_error_t yuv_sp_to_bgr_u8_sc(
100 const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv,
101 size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width,
102 size_t height, bool is_nv21) KLEIDICV_STREAMING {
103 378 YUVSpToBGR operation{is_nv21};
104 1134 return yuv2rgbx_operation(operation, src_y, src_y_stride, src_uv,
105 378 src_uv_stride, dst, dst_stride, width, height);
106 378 }
107
108 KLEIDICV_TARGET_FN_ATTRS
109 378 static kleidicv_error_t yuv_sp_to_bgra_u8_sc(
110 const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv,
111 size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width,
112 size_t height, bool is_nv21) KLEIDICV_STREAMING {
113 378 YUVSpToBGRA operation{is_nv21};
114 1134 return yuv2rgbx_operation(operation, src_y, src_y_stride, src_uv,
115 378 src_uv_stride, dst, dst_stride, width, height);
116 378 }
117
118 } // namespace KLEIDICV_TARGET_NAMESPACE
119
120 #endif // KLEIDICV_YUV_SP_TO_RGB_SC_H
121