Notcurses 3.0.13
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
base64.h
Go to the documentation of this file.
1#ifndef NOTCURSES_BASE64
2#define NOTCURSES_BASE64
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8// convert a base64 character into its equivalent integer 0..63
9static inline int
10b64idx(char b64){
11 if(b64 >= 'A' && b64 <= 'Z'){
12 return b64 - 'A';
13 }else if(b64 >= 'a' && b64 <= 'z'){
14 return b64 - 'a' + 26;
15 }else if(b64 >= '0' && b64 <= '9'){
16 return b64 - '0' + 52;
17 }else if(b64 == '+'){
18 return 62;
19 }else{
20 return 63;
21 }
22}
23
24// lookup table for base64
25static unsigned const char b64subs[] =
26 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
27
28// every 3 RGBA pixels (96 bits) become 16 base64-encoded bytes (128 bits). if
29// there are only 2 pixels available, those 64 bits become 12 bytes. if there
30// is only 1 pixel available, those 32 bits become 8 bytes. (pcount + 1) * 4
31// bytes are used, plus a null terminator. we thus must receive 17.
32// wipe is referring to the sprixcell state, i.e. whether it was annihilated.
33// it always makes a pixel transparent (by setting alpha to 0). otherwise, we
34// check the pixel against the transcolor. matches (and sufficiently low alpha)
35// are likewise flattened to alpha=0.
36static inline void
37base64_rgba3(const uint32_t pixels[static 3], size_t pcount,
38 char b64[static 17], bool wipe[static 3], uint32_t transcolor){
39 uint32_t pixel = pixels[0];
40 unsigned r = ncpixel_r(pixel);
41 unsigned g = ncpixel_g(pixel);
42 unsigned b = ncpixel_b(pixel);
43 // we go ahead and take advantage of kitty's ability to reproduce 8-bit
44 // alphas by copying it in directly, rather than mapping to {0, 255}.
45 unsigned a = ncpixel_a(pixel);
46 if(wipe[0] || rgba_trans_p(pixel, transcolor)){
47 a = 0;
48 }
49 b64[0] = b64subs[(r & 0xfc) >> 2];
50 b64[1] = b64subs[(r & 0x3 << 4) | ((g & 0xf0) >> 4)];
51 b64[2] = b64subs[((g & 0xf) << 2) | ((b & 0xc0) >> 6)];
52 b64[3] = b64subs[b & 0x3f];
53 b64[4] = b64subs[(a & 0xfc) >> 2];
54 if(pcount == 1){
55 b64[5] = b64subs[(a & 0x3) << 4];
56 b64[6] = '=';
57 b64[7] = '=';
58 b64[8] = '\0';
59 return;
60 }
61 b64[5] = (a & 0x3) << 4;
62 pixel = pixels[1];
63 r = ncpixel_r(pixel);
64 g = ncpixel_g(pixel);
65 b = ncpixel_b(pixel);
66 a = wipe[1] ? 0 : rgba_trans_p(pixel, transcolor) ? 0 : 255;
67 b64[5] = b64subs[b64[5] | ((r & 0xf0) >> 4)];
68 b64[6] = b64subs[((r & 0xf) << 2) | ((g & 0xc0) >> 6u)];
69 b64[7] = b64subs[g & 0x3f];
70 b64[8] = b64subs[(b & 0xfc) >> 2];
71 b64[9] = b64subs[((b & 0x3) << 4) | ((a & 0xf0) >> 4)];
72 if(pcount == 2){
73 b64[10] = b64subs[(a & 0xf) << 2];
74 b64[11] = '=';
75 b64[12] = '\0';
76 return;
77 }
78 b64[10] = (a & 0xf) << 2;
79 pixel = pixels[2];
80 r = ncpixel_r(pixel);
81 g = ncpixel_g(pixel);
82 b = ncpixel_b(pixel);
83 a = wipe[2] ? 0 : rgba_trans_p(pixel, transcolor) ? 0 : 255;
84 b64[10] = b64subs[b64[10] | ((r & 0xc0) >> 6)];
85 b64[11] = b64subs[r & 0x3f];
86 b64[12] = b64subs[(g & 0xfc) >> 2];
87 b64[13] = b64subs[((g & 0x3) << 4) | ((b & 0xf0) >> 4)];
88 b64[14] = b64subs[((b & 0xf) << 2) | ((a & 0xc0) >> 6)];
89 b64[15] = b64subs[a & 0x3f];
90 b64[16] = '\0';
91}
92
93// convert 3 8-bit bytes into 4 base64-encoded characters
94static inline void
95base64x3(const unsigned char* src, char* b64){
96 uint8_t a = src[0] >> 2u;
97 uint8_t b = ((src[0] & 0x3u) << 4u) + ((src[1] & 0xf0u) >> 4u);
98 uint8_t c = ((src[1] & 0x0fu) << 2u) + ((src[2] & 0xc0u) >> 6u);
99 uint8_t d = src[2] & 0x3f;
100 b64[0] = b64subs[a];
101 b64[1] = b64subs[b];
102 b64[2] = b64subs[c];
103 b64[3] = b64subs[d];
104}
105
106// finalize a base64 stream with 3 or fewer 8-bit bytes
107static inline void
108base64final(const unsigned char* src, char* b64, size_t b){
109 if(b == 3){
110 base64x3(src, b64);
111 }else if(b == 2){
112 uint8_t s0 = src[0] >> 2u;
113 uint8_t s1 = ((src[0] & 0x3u) << 4u) + ((src[1] & 0xf0u) >> 4u);
114 uint8_t s2 = ((src[1] & 0x0fu) << 2u);
115 b64[0] = b64subs[s0];
116 b64[1] = b64subs[s1];
117 b64[2] = b64subs[s2];
118 b64[3] = '=';
119 }else{ // b == 1
120 uint8_t s0 = src[0] >> 2u;
121 uint8_t s1 = (src[0] & 0x3u) << 4u;
122 b64[0] = b64subs[s0];
123 b64[1] = b64subs[s1];
124 b64[2] = '=';
125 b64[3] = '=';
126 }
127}
128
129#ifdef __cplusplus
130}
131#endif
132
133#endif
const nccell * c
Definition egcpool.h:296
int r
Definition fbuf.h:226