ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
neon/mono.c
Go to the documentation of this file.
1#if SIMD_SUPPORT_NEON
2#define SIMD_CELL_NEON 1
3#define SIMD_CELL_ISA neon
4#include "../simd/lookup.c"
7// Keep NEON's uniform-length UTF-8 compaction. ANSI state and row endings
8// are handled by the common emitter; this writes only complete glyph bytes.
9void simd_emit_mono_neon(outbuf_t *out, const uint32_t *glyph, size_t count) {
10 size_t i = 0;
11 ob_reserve(out, count * 4);
12 for (; count - i >= 16; i += 16) {
13 uint8x16x4_t bytes = vld4q_u8((const uint8_t *)(glyph + i));
14 uint8x16_t first = bytes.val[0];
15 uint8x16_t lengths = vdupq_n_u8(1);
16 lengths = vbslq_u8(vcgeq_u8(first, vdupq_n_u8(0xc0)), vdupq_n_u8(2), lengths);
17 lengths = vbslq_u8(vcgeq_u8(first, vdupq_n_u8(0xe0)), vdupq_n_u8(3), lengths);
18 lengths = vbslq_u8(vcgeq_u8(first, vdupq_n_u8(0xf0)), vdupq_n_u8(4), lengths);
19 uint8_t uniform = vgetq_lane_u8(lengths, 0);
20 uint8_t equal[16];
21 vst1q_u8(equal, vceqq_u8(lengths, vdupq_n_u8(uniform)));
22 bool same = true;
23 for (unsigned j = 0; j < 16; ++j)
24 same = same && equal[j] == 255;
25 uint8_t *pos = (uint8_t *)out->buf + out->len;
26 if (same) {
27 if (uniform == 1)
28 vst1q_u8(pos, bytes.val[0]);
29 else if (uniform == 2) {
30 uint8x16x2_t interleaved = {{bytes.val[0], bytes.val[1]}};
31 vst2q_u8(pos, interleaved);
32 } else if (uniform == 3) {
33 uint8x16x3_t interleaved = {{bytes.val[0], bytes.val[1], bytes.val[2]}};
34 vst3q_u8(pos, interleaved);
35 } else
36 vst4q_u8(pos, bytes);
37 out->len += (size_t)uniform * 16;
38 } else {
39 // Mixed widths retain all four gathered byte streams and compact in order.
40 uint8_t byte0[16], byte1[16], byte2[16], byte3[16], len[16];
41 vst1q_u8(byte0, bytes.val[0]);
42 vst1q_u8(byte1, bytes.val[1]);
43 vst1q_u8(byte2, bytes.val[2]);
44 vst1q_u8(byte3, bytes.val[3]);
45 vst1q_u8(len, lengths);
46 for (unsigned j = 0; j < 16; ++j) {
47 *pos++ = byte0[j];
48 if (len[j] > 1)
49 *pos++ = byte1[j];
50 if (len[j] > 2)
51 *pos++ = byte2[j];
52 if (len[j] > 3)
53 *pos++ = byte3[j];
54 }
55 out->len = (size_t)(pos - (uint8_t *)out->buf);
56 }
57 }
58 for (; i < count; ++i) {
59 const uint8_t *bytes = (const uint8_t *)(glyph + i);
60 size_t length = bytes[0] < 128 ? 1 : bytes[0] < 224 ? 2 : bytes[0] < 240 ? 3 : 4;
61 ob_write(out, bytes, length);
62 }
63 ob_term(out);
64}
65char *render_ascii_mono_neon(const image_t *image, const char *palette) {
66 return render_ascii_cells_neon(image, palette, ASCII_COLOR_NONE, false);
67}
68#endif
void simd_emit_mono_neon(outbuf_t *out, const uint32_t *glyph, size_t count)
unsigned int uint32_t
Definition common.h:62
unsigned char uint8_t
Definition common.h:60
void ob_term(outbuf_t *ob)
Append null terminator to buffer.
void ob_reserve(outbuf_t *ob, size_t need)
Dynamic output buffer (auto-expanding).
void ob_write(outbuf_t *ob, const void *s, size_t n)
Append a string to buffer.
char * render_ascii_cells_neon(const image_t *, const char *, ascii_color_t, bool)
NEON-optimized ASCII rendering functions.
static bool size_t gotel_query_t * out
Definition queries.h:8
SIMD-friendly storage for one RGB pixel. r, g, and b hold the color channels and padding keeps the la...
Dynamic output buffer (auto-expanding).