MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ rgba_to_gray() [1/2]

MAYAFLUX_API void MayaFlux::Kinesis::Vision::rgba_to_gray ( std::span< const float >  rgba,
std::span< float >  dst,
uint32_t  w,
uint32_t  h 
)

Convert RGBA to luminance gray using BT.601 coefficients.

Output is one float per pixel. Alpha channel is discarded. Coefficients: R*0.299 + G*0.587 + B*0.114

Parameters
rgbaInterleaved RGBA span, size must be w * h * 4.
dstOutput span, size must be w * h.
wImage width in pixels.
hImage height in pixels.

Definition at line 18 of file PixelOps.cpp.

19{
20 const size_t n = static_cast<size_t>(w) * h;
21
22 P::for_each(P::par_unseq,
23 std::views::iota(uint32_t { 0 }, h).begin(),
24 std::views::iota(uint32_t { 0 }, h).end(),
25 [&](uint32_t row) {
26 const float* src_row = rgba.data() + static_cast<size_t>(row) * w * 4;
27 float* dst_row = dst.data() + static_cast<size_t>(row) * w;
28
29#ifdef MAYAFLUX_ARCH_X64
30 uint32_t px = 0;
31 for (; px + 8 <= w; px += 8) {
32 __m128 a0 = _mm_loadu_ps(src_row + px * 4);
33 __m128 a1 = _mm_loadu_ps(src_row + px * 4 + 4);
34 __m128 a2 = _mm_loadu_ps(src_row + px * 4 + 8);
35 __m128 a3 = _mm_loadu_ps(src_row + px * 4 + 12);
36 _MM_TRANSPOSE4_PS(a0, a1, a2, a3);
37 __m128 lo = _mm_fmadd_ps(a0, _mm_set1_ps(0.299F),
38 _mm_fmadd_ps(a1, _mm_set1_ps(0.587F),
39 _mm_mul_ps(a2, _mm_set1_ps(0.114F))));
40
41 __m128 b0 = _mm_loadu_ps(src_row + px * 4 + 16);
42 __m128 b1 = _mm_loadu_ps(src_row + px * 4 + 20);
43 __m128 b2 = _mm_loadu_ps(src_row + px * 4 + 24);
44 __m128 b3 = _mm_loadu_ps(src_row + px * 4 + 28);
45 _MM_TRANSPOSE4_PS(b0, b1, b2, b3);
46 __m128 hi = _mm_fmadd_ps(b0, _mm_set1_ps(0.299F),
47 _mm_fmadd_ps(b1, _mm_set1_ps(0.587F),
48 _mm_mul_ps(b2, _mm_set1_ps(0.114F))));
49
50 _mm256_storeu_ps(dst_row + px, _mm256_set_m128(hi, lo));
51 }
52 for (; px < w; ++px) {
53 const size_t p = px * 4;
54 dst_row[px] = src_row[p] * 0.299F
55 + src_row[p + 1] * 0.587F
56 + src_row[p + 2] * 0.114F;
57 }
58
59#elif defined(MAYAFLUX_ARCH_ARM64)
60 const float32x4_t k_r = vdupq_n_f32(0.299F);
61 const float32x4_t k_g = vdupq_n_f32(0.587F);
62 const float32x4_t k_b = vdupq_n_f32(0.114F);
63 uint32_t px = 0;
64 for (; px + 4 <= w; px += 4) {
65 float32x4x4_t p = vld4q_f32(src_row + px * 4);
66 vst1q_f32(dst_row + px,
67 vmlaq_f32(vmlaq_f32(vmulq_f32(p.val[0], k_r), p.val[1], k_g), p.val[2], k_b));
68 }
69 for (; px < w; ++px) {
70 const size_t p = px * 4;
71 dst_row[px] = src_row[p] * 0.299F
72 + src_row[p + 1] * 0.587F
73 + src_row[p + 2] * 0.114F;
74 }
75
76#else
77 for (uint32_t px = 0; px < w; ++px) {
78 const size_t p = px * 4;
79 dst_row[px] = src_row[p] * 0.299F
80 + src_row[p + 1] * 0.587F
81 + src_row[p + 2] * 0.114F;
82 }
83#endif
84 });
85}
uint32_t h
Definition InkPress.cpp:28
float lo
float hi

References h, hi, and lo.

Referenced by rgba_to_gray(), and MayaFlux::Kinesis::Vision::VisionExecutor::run().

+ Here is the caller graph for this function: