Merge remote-tracking branch 'cockos/main' into next
[wdl/wdl-tale.git] / WDL / wdl_base64.h
blobd4ffec87114d3960689ff4e9f2bad6c84976fd03
1 #ifndef _WDL_BASE64_H_
2 #define _WDL_BASE64_H_
4 #ifndef WDL_BASE64_FUNCDECL
5 #define WDL_BASE64_FUNCDECL static
6 #endif
8 static const char wdl_base64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
9 WDL_BASE64_FUNCDECL void wdl_base64encode(const unsigned char *in, char *out, int len)
11 while (len >= 6)
13 const int accum = (in[0] << 16) + (in[1] << 8) + in[2];
14 const int accum2 = (in[3] << 16) + (in[4] << 8) + in[5];
15 out[0] = wdl_base64_alphabet[(accum >> 18) & 0x3F];
16 out[1] = wdl_base64_alphabet[(accum >> 12) & 0x3F];
17 out[2] = wdl_base64_alphabet[(accum >> 6) & 0x3F];
18 out[3] = wdl_base64_alphabet[accum & 0x3F];
19 out[4] = wdl_base64_alphabet[(accum2 >> 18) & 0x3F];
20 out[5] = wdl_base64_alphabet[(accum2 >> 12) & 0x3F];
21 out[6] = wdl_base64_alphabet[(accum2 >> 6) & 0x3F];
22 out[7] = wdl_base64_alphabet[accum2 & 0x3F];
23 out+=8;
24 in+=6;
25 len-=6;
28 if (len >= 3)
30 const int accum = (in[0]<<16)|(in[1]<<8)|in[2];
31 out[0] = wdl_base64_alphabet[(accum >> 18) & 0x3F];
32 out[1] = wdl_base64_alphabet[(accum >> 12) & 0x3F];
33 out[2] = wdl_base64_alphabet[(accum >> 6) & 0x3F];
34 out[3] = wdl_base64_alphabet[accum & 0x3F];
35 in+=3;
36 len-=3;
37 out+=4;
40 if (len>0)
42 if (len == 2)
44 const int accum = (in[0] << 8) | in[1];
45 out[0] = wdl_base64_alphabet[(accum >> 10) & 0x3F];
46 out[1] = wdl_base64_alphabet[(accum >> 4) & 0x3F];
47 out[2] = wdl_base64_alphabet[(accum & 0xF)<<2];
49 else
51 const int accum = in[0];
52 out[0] = wdl_base64_alphabet[(accum >> 2) & 0x3F];
53 out[1] = wdl_base64_alphabet[(accum & 0x3)<<4];
54 out[2]='=';
56 out[3]='=';
57 out+=4;
60 out[0]=0;
63 WDL_BASE64_FUNCDECL int wdl_base64decode(const char *src, unsigned char *dest, int destsize)
65 static const char *tab = // poolable string
66 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
67 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
68 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3e\xff\xff\xff\x3f"
69 "\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\xff\xff\xff\xff\xff\xff"
70 "\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
71 "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xff\xff\xff\xff\xff"
72 "\xff\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28"
73 "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\xff\xff\xff\xff\xff"
74 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
75 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
76 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
77 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
78 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
79 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
80 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
81 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
84 unsigned int accum=0;
85 int nbits=0, wpos=0;
87 if (destsize <= 0) return 0;
89 for (;;)
91 const int v=(int)tab[*(unsigned char *)src++];
92 if (v<0) return wpos;
94 accum += v;
95 nbits += 6;
97 if (nbits >= 8)
99 nbits-=8;
100 dest[wpos] = (accum>>nbits)&0xff;
101 if (++wpos >= destsize) return wpos;
103 accum <<= 6;
108 #endif