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

Go to the source code of this file.

Functions

void simd_quantize_SIMD_CELL_ISA (const uint32_t *rgb, uint32_t *out, size_t count, unsigned colors)
size_t simd_run_SIMD_CELL_ISA (const uint32_t *glyph, const uint32_t *fg, const uint32_t *bg, size_t count)

Function Documentation

◆ simd_quantize_SIMD_CELL_ISA()

void simd_quantize_SIMD_CELL_ISA ( const uint32_t * rgb,
uint32_t * out,
size_t count,
unsigned colors )

Definition at line 4 of file quantize.c.

4 {
5 static const int palette[16][3] = {{0, 0, 0}, {128, 0, 0}, {0, 128, 0}, {128, 128, 0},
6 {0, 0, 128}, {128, 0, 128}, {0, 128, 128}, {192, 192, 192},
7 {128, 128, 128}, {255, 0, 0}, {0, 255, 0}, {255, 255, 0},
8 {0, 0, 255}, {255, 0, 255}, {0, 255, 255}, {255, 255, 255}};
9 size_t i = 0;
10 for (; HAS_BLOCK; i += LANES) {
12 (void)active;
13 vec_t packed = LOAD(rgb + i);
14 vec_t r = AND(SHR(packed, 16), SET(255)), g = AND(SHR(packed, 8), SET(255)), b = AND(packed, SET(255));
15 vec_t index = SET(0);
16 if (colors == 16) {
17 vec_t best = SET(0x7fffffff);
18 for (int c = 0; c < 16; ++c) {
19 vec_t dr = SUB(r, SET(palette[c][0])), dg = SUB(g, SET(palette[c][1])), db = SUB(b, SET(palette[c][2]));
20 vec_t distance = ADD(ADD(SQUARE(dr), SQUARE(dg)), SQUARE(db));
21 index = SELECT(LT(distance, best), SET(c), index);
22 best = SELECT(LT(distance, best), distance, best);
23 }
24 } else {
25 // Exact nearest nonuniform xterm cube, with ties choosing the lower level.
26 vec_t ri = SET(0), gi = SET(0), bi = SET(0);
27 const int thresholds[5] = {47, 115, 155, 195, 235};
28 for (int c = 0; c < 5; ++c) {
29 ri = ADD(ri, SELECT(LT(SET(thresholds[c]), r), SET(1), SET(0)));
30 gi = ADD(gi, SELECT(LT(SET(thresholds[c]), g), SET(1), SET(0)));
31 bi = ADD(bi, SELECT(LT(SET(thresholds[c]), b), SET(1), SET(0)));
32 }
33 vec_t rl = SELECT(EQ(ri, SET(0)), SET(0), ADD(SET(55), MUL(ri, SET(40))));
34 vec_t gl = SELECT(EQ(gi, SET(0)), SET(0), ADD(SET(55), MUL(gi, SET(40))));
35 vec_t bl = SELECT(EQ(bi, SET(0)), SET(0), ADD(SET(55), MUL(bi, SET(40))));
36 vec_t dr = SUB(r, rl), dg = SUB(g, gl), db = SUB(b, bl);
37 vec_t error = ADD(ADD(SQUARE(dr), SQUARE(dg)), SQUARE(db));
38 index = ADD(SET(16), ADD(MUL(ri, SET(36)), ADD(MUL(gi, SET(6)), bi)));
39 vec_t gray = DIV(SUB(ADD(ADD(r, g), b), SET(9)), 30);
40 gray = SELECT(LT(gray, SET(0)), SET(0), gray);
41 gray = SELECT(LT(SET(23), gray), SET(23), gray);
42 vec_t level = ADD(SET(8), MUL(gray, SET(10)));
43 dr = SUB(r, level);
44 dg = SUB(g, level);
45 db = SUB(b, level);
46 vec_t gray_error = ADD(ADD(SQUARE(dr), SQUARE(dg)), SQUARE(db));
47 index = SELECT(LT(gray_error, error), ADD(SET(232), gray), index);
48 }
49 STORE(out + i, index);
50 }
51 if (i < count)
52 simd_quantize_scalar(rgb + i, out + i, count - i, colors);
53}
void simd_quantize_scalar(const uint32_t *rgb, uint32_t *out, size_t count, unsigned colors)
Definition cells.c:18
unsigned char colors[(512 *256 *2) *3]
Definition fft.c:22
static bool size_t index
Definition queries.h:8
static bool size_t gotel_query_t * out
Definition queries.h:8
#define STORE(p, v)
Definition vector.h:71
#define BEGIN_BLOCK
Definition vector.h:72
#define LOAD(p)
Definition vector.h:70
#define MUL(a, b)
Definition vector.h:60
#define AND(a, b)
Definition vector.h:64
#define DIV(a, n)
Definition vector.h:61
#define SET(n)
Definition vector.h:57
#define SELECT(mask, a, b)
Definition vector.h:69
#define SHR(a, n)
Definition vector.h:63
#define EQ(a, b)
Definition vector.h:67
#define LT(a, b)
Definition vector.h:66
#define LANES
Definition vector.h:35
#define SQUARE(v)
Definition vector.h:76
#define ADD(a, b)
Definition vector.h:58
#define HAS_BLOCK
Definition vector.h:73
#define SUB(a, b)
Definition vector.h:59

References ADD, AND, BEGIN_BLOCK, colors, DIV, EQ, HAS_BLOCK, index, LANES, LOAD, LT, MUL, out, SELECT, SET, SHR, simd_quantize_scalar(), SQUARE, STORE, and SUB.

◆ simd_run_SIMD_CELL_ISA()

size_t simd_run_SIMD_CELL_ISA ( const uint32_t * glyph,
const uint32_t * fg,
const uint32_t * bg,
size_t count )

Definition at line 55 of file quantize.c.

55 {
56 if (!count)
57 return 0;
58 size_t i = 0;
59 for (; HAS_BLOCK; i += LANES) {
61 (void)active;
62 vec_t ga = LOAD(glyph + i), fa = LOAD(fg + i), ba = LOAD(bg + i);
63#if defined(SIMD_CELL_SVE)
64 svbool_t equal =
65 BOTH(EQ(ga, SET((int32_t)glyph[0])), BOTH(EQ(fa, SET((int32_t)fg[0])), EQ(ba, SET((int32_t)bg[0]))));
66 if (svcntp_b32(pg, equal) == active)
67 continue;
68 uint32_t flags[64];
69 svst1_u32(pg, flags, svsel_u32(equal, svdup_u32(1), svdup_u32(0)));
70 for (size_t j = 0; j < active; ++j)
71 if (!flags[j])
72 return i + j;
73#else
74 vec_t equal = BOTH(EQ(ga, SET((int32_t)glyph[0])), BOTH(EQ(fa, SET((int32_t)fg[0])), EQ(ba, SET((int32_t)bg[0]))));
75#if defined(SIMD_CELL_AVX2)
76 unsigned mask = (unsigned)_mm256_movemask_ps((__m256)equal);
77 if (mask != 255)
78 return i + (size_t)__builtin_ctz((~mask) & 255);
79#elif !defined(SIMD_CELL_NEON)
80 unsigned mask = (unsigned)_mm_movemask_ps((__m128)equal);
81 if (mask != 15)
82 return i + (size_t)__builtin_ctz((~mask) & 15);
83#else
84 uint32x4_t lanes = (uint32x4_t)equal;
85 uint32x2_t minimum = vmin_u32(vget_low_u32(lanes), vget_high_u32(lanes));
86 minimum = vpmin_u32(minimum, minimum);
87 if (vget_lane_u32(minimum, 0) == UINT32_MAX)
88 continue;
89 uint32_t flags[4];
90 STORE(flags, equal);
91 for (size_t j = 0; j < active; ++j)
92 if (!flags[j])
93 return i + j;
94#endif
95#endif
96 }
97 for (; i < count && glyph[i] == glyph[0] && fg[i] == fg[0] && bg[i] == bg[0]; ++i) {
98 }
99 return i < count ? i : count;
100}
unsigned int uint32_t
Definition common.h:62
#define BOTH(a, b)
Definition vector.h:68

References BEGIN_BLOCK, BOTH, EQ, HAS_BLOCK, LANES, LOAD, SET, and STORE.