ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
sve/luminance.c
Go to the documentation of this file.
4#include <string.h>
5#include <arm_sve.h>
6
7int glyph_shape_correlation_sve(const int16_t samples[16], const int16_t mask[16]) {
8 int sum = 0;
9 for (uint64_t i = 0; i < 16; i += svcntw()) {
10 svbool_t active = svwhilelt_b32(i, (uint64_t)16);
11 svint32_t a = svld1sh_s32(active, samples + i);
12 svint32_t b = svld1sh_s32(active, mask + i);
13 sum += (int)svaddv_s32(active, svmul_s32_x(active, a, b));
14 }
15 return sum;
16}
17void simd_luminance_sve(const uint8_t *rgb, uint8_t *out, size_t width) {
18 const rgb_pixel_t *row = (const rgb_pixel_t *)rgb;
19 size_t x = 0;
20 while (x < width) {
21 // Widening consumes half the byte lanes; predicate the active halfword lanes.
22 size_t process_count = width - x < svcnth() ? width - x : svcnth();
23 svbool_t pg_active = svwhilelt_b8((uint64_t)0, (uint64_t)process_count);
24 // Retain the renderer's channel scratch layout before widening arithmetic.
25 uint8_t r_array[256], g_array[256], b_array[256]; // Max SVE vector size
26 for (int j = 0; j < process_count; j++) {
27 if (x + j < width) {
28 r_array[j] = row[x + j].r;
29 g_array[j] = row[x + j].g;
30 b_array[j] = row[x + j].b;
31 }
32 }
33
34 // Load into SVE vectors
35 svuint8_t r_vec = svld1_u8(pg_active, r_array);
36 svuint8_t g_vec = svld1_u8(pg_active, g_array);
37 svuint8_t b_vec = svld1_u8(pg_active, b_array);
38
39 // Convert to 16-bit for arithmetic
40 svuint16_t r_16 = svunpklo_u16(r_vec);
41 svuint16_t g_16 = svunpklo_u16(g_vec);
42 svuint16_t b_16 = svunpklo_u16(b_vec);
43
44 // Calculate luminance: (77*R + 150*G + 29*B + 128) >> 8
45 svuint16_t luma = svmul_n_u16_x(svptrue_b16(), r_16, LUMA_RED);
46 luma = svmla_n_u16_x(svptrue_b16(), luma, g_16, LUMA_GREEN);
47 luma = svmla_n_u16_x(svptrue_b16(), luma, b_16, LUMA_BLUE);
48 luma = svadd_n_u16_x(svptrue_b16(), luma, LUMA_THRESHOLD);
49 luma = svlsr_n_u16_x(svptrue_b16(), luma, 8);
50
51 // Store u16 luminance values (SVE1 compatible - no SVE2 narrowing intrinsics)
52 // After right-shift by 8, values are already in 0-255 range
53 uint16_t luma_temp[256];
54 svst1_u16(svptrue_b16(), luma_temp, luma);
55
56 // Convert to u8 array for ASCII lookup
57 uint8_t luma_array[256];
58 for (int j = 0; j < process_count; j++) {
59 luma_array[j] = (uint8_t)luma_temp[j];
60 }
61
62 memcpy(out + x, luma_array, process_count);
63 x += process_count;
64 }
65}
unsigned int width
Definition fft.c:23
unsigned short uint16_t
Definition common.h:61
unsigned long long uint64_t
Definition common.h:63
unsigned char uint8_t
Definition common.h:60
#define LUMA_BLUE
Luminance blue coefficient (0.114 * 256 = 29).
#define LUMA_GREEN
Luminance green coefficient (0.587 * 256 = 150).
#define LUMA_THRESHOLD
Luminance threshold for rounding.
#define LUMA_RED
Luminance red coefficient (0.299 * 256 = 77).
static bool size_t gotel_query_t * out
Definition queries.h:8
🔤 String Manipulation and Shell Escaping Utilities
uint8_t b
Blue color component (0-255).
uint8_t g
Green color component (0-255).
uint8_t r
Red color component (0-255).
void simd_luminance_sve(const uint8_t *rgb, uint8_t *out, size_t width)
int glyph_shape_correlation_sve(const int16_t samples[16], const int16_t mask[16])
SIMD-optimized ASCII conversion interface.