ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
luminance.c File Reference

Go to the source code of this file.

Functions

void simd_luminance_ssse3 (const uint8_t *rgb, uint8_t *out, size_t width)

Function Documentation

◆ simd_luminance_ssse3()

void simd_luminance_ssse3 ( const uint8_t * rgb,
uint8_t * out,
size_t width )

Definition at line 5 of file ssse3/luminance.c.

5 {
6 const rgb_pixel_t *row = (const rgb_pixel_t *)rgb;
7 size_t x = 0;
8 for (; width - x >= 16; x += 16) {
9 // Manual deinterleave RGB components (SSSE3 limitation vs NEON's vld3q_u8)
10 uint8_t r_array[16], g_array[16], b_array[16];
11 for (int j = 0; j < 16; j++) {
12 r_array[j] = row[x + j].r;
13 g_array[j] = row[x + j].g;
14 b_array[j] = row[x + j].b;
15 }
16
17 // Process 16 pixels in two 8-pixel SSSE3 batches (same as SSE2 approach)
18 __m128i r_vec_lo = _mm_loadl_epi64((__m128i *)(r_array + 0));
19 __m128i r_vec_hi = _mm_loadl_epi64((__m128i *)(r_array + 8));
20 __m128i g_vec_lo = _mm_loadl_epi64((__m128i *)(g_array + 0));
21 __m128i g_vec_hi = _mm_loadl_epi64((__m128i *)(g_array + 8));
22 __m128i b_vec_lo = _mm_loadl_epi64((__m128i *)(b_array + 0));
23 __m128i b_vec_hi = _mm_loadl_epi64((__m128i *)(b_array + 8));
24
25 // Process first 8 pixels
26 __m128i r_16_lo = _mm_unpacklo_epi8(r_vec_lo, _mm_setzero_si128());
27 __m128i g_16_lo = _mm_unpacklo_epi8(g_vec_lo, _mm_setzero_si128());
28 __m128i b_16_lo = _mm_unpacklo_epi8(b_vec_lo, _mm_setzero_si128());
29
30 __m128i luma_r_lo = _mm_mullo_epi16(r_16_lo, _mm_set1_epi16(LUMA_RED));
31 __m128i luma_g_lo = _mm_mullo_epi16(g_16_lo, _mm_set1_epi16(LUMA_GREEN));
32 __m128i luma_b_lo = _mm_mullo_epi16(b_16_lo, _mm_set1_epi16(LUMA_BLUE));
33
34 __m128i luma_sum_lo = _mm_add_epi16(luma_r_lo, luma_g_lo);
35 luma_sum_lo = _mm_add_epi16(luma_sum_lo, luma_b_lo);
36 luma_sum_lo = _mm_add_epi16(luma_sum_lo, _mm_set1_epi16(LUMA_THRESHOLD));
37 luma_sum_lo = _mm_srli_epi16(luma_sum_lo, 8);
38
39 // Process second 8 pixels
40 __m128i r_16_hi = _mm_unpacklo_epi8(r_vec_hi, _mm_setzero_si128());
41 __m128i g_16_hi = _mm_unpacklo_epi8(g_vec_hi, _mm_setzero_si128());
42 __m128i b_16_hi = _mm_unpacklo_epi8(b_vec_hi, _mm_setzero_si128());
43
44 __m128i luma_r_hi = _mm_mullo_epi16(r_16_hi, _mm_set1_epi16(LUMA_RED));
45 __m128i luma_g_hi = _mm_mullo_epi16(g_16_hi, _mm_set1_epi16(LUMA_GREEN));
46 __m128i luma_b_hi = _mm_mullo_epi16(b_16_hi, _mm_set1_epi16(LUMA_BLUE));
47
48 __m128i luma_sum_hi = _mm_add_epi16(luma_r_hi, luma_g_hi);
49 luma_sum_hi = _mm_add_epi16(luma_sum_hi, luma_b_hi);
50 luma_sum_hi = _mm_add_epi16(luma_sum_hi, _mm_set1_epi16(LUMA_THRESHOLD));
51 luma_sum_hi = _mm_srli_epi16(luma_sum_hi, 8);
52
53 // Pack and store
54 __m128i luminance_lo = _mm_packus_epi16(luma_sum_lo, _mm_setzero_si128());
55 __m128i luminance_hi = _mm_packus_epi16(luma_sum_hi, _mm_setzero_si128());
56
57 uint8_t luma_array[16];
58 _mm_storel_epi64((__m128i *)(luma_array + 0), luminance_lo);
59 _mm_storel_epi64((__m128i *)(luma_array + 8), luminance_hi);
60 memcpy(out + x, luma_array, 16);
61 }
62 simd_luminance_scalar((const uint8_t *)(row + x), out + x, width - x);
63}
void simd_luminance_scalar(const uint8_t *rgb, uint8_t *out, size_t count)
Definition dispatch.c:57
unsigned int width
Definition fft.c:23
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
uint8_t b
Blue color component (0-255).
uint8_t g
Green color component (0-255).
uint8_t r
Red color component (0-255).

References rgb_pixel_t::b, rgb_pixel_t::g, LUMA_BLUE, LUMA_GREEN, LUMA_RED, LUMA_THRESHOLD, out, rgb_pixel_t::r, simd_luminance_scalar(), and width.