1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2
3 #include "bl_util.h"
4
5 #include <string.h>
6 #include <stdlib.h> /* getenv */
7 #ifdef HAVE_GETPWUID
8 #include <pwd.h>
9 #endif
10
11 #include "bl_unistd.h" /* bl_getuid */
12 #include "bl_debug.h"
13
14 /* --- static functions --- */
15
hex_to_int(char c)16 static int hex_to_int(char c) {
17 if ('0' <= c && c <= '9') {
18 return c - '0';
19 } else {
20 c &= 0xdf;
21
22 if ('A' <= c && c <= 'F') {
23 return c - 'A' + 10;
24 }
25 }
26
27 return -1;
28 }
29
get_pc(int h,u_int32_t m1,u_int32_t m2)30 static inline int get_pc(int h, u_int32_t m1, u_int32_t m2) {
31 if (h < 60) {
32 return m1 + (m2 - m1) * h / 60;
33 } else if (h < 180) {
34 return m2;
35 } else if (h < 240) {
36 return m1 + (m2 - m1) * (240 - h) / 60;
37 } else {
38 return m1;
39 }
40 }
41
42 /* --- global functions --- */
43
bl_hex_decode(char * decoded,const char * encoded,size_t e_len)44 size_t bl_hex_decode(char *decoded, const char *encoded, size_t e_len) {
45 size_t pos;
46 char *p = decoded;
47
48 for (pos = 0; e_len > pos + 1; pos += 2) {
49 int i1 = hex_to_int(encoded[pos]);
50 int i2 = hex_to_int(encoded[pos + 1]);
51
52 if (i1 < 0 || i2 < 0) {
53 break;
54 }
55
56 *(p++) = i1 * 16 + i2;
57 }
58
59 return (p - decoded);
60 }
61
62
bl_hex_encode(char * encoded,const char * decoded,size_t d_len)63 size_t bl_hex_encode(char *encoded, const char *decoded, size_t d_len) {
64 size_t pos;
65 char *p = encoded;
66
67 for (pos = 0; d_len > pos; pos ++) {
68 int h1 = (decoded[pos] >> 4) & 0xf;
69 int h2 = decoded[pos] & 0xf;
70
71 *(p++) = (h1 > 9) ? ('a' + h1 - 10) : ('0' + h1);
72 *(p++) = (h2 > 9) ? ('a' + h2 - 10) : ('0' + h2);
73 }
74
75 return (p - encoded);
76 }
77
bl_base64_decode(char * decoded,const char * encoded,size_t e_len)78 size_t bl_base64_decode(char *decoded, const char *encoded, size_t e_len) {
79 size_t d_pos;
80 size_t e_pos;
81 /* ASCII -> Base64 order */
82 int8_t conv_tbl[] = {/* 0x2b - */
83 62, -1, -1, -1, 63,
84 /* 0x30 - */
85 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
86 /* 0x40 - */
87 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
88 /* 0x50 - */
89 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
90 /* 0x60 - */
91 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
92 /* 0x70 - 7a */
93 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
94
95 d_pos = e_pos = 0;
96
97 while (e_len >= e_pos + 4) {
98 size_t count;
99 int8_t bytes[4];
100
101 for (count = 0; count < 4; e_pos++) {
102 if (encoded[e_pos] < 0x2b || 0x7a < encoded[e_pos] ||
103 (bytes[count] = conv_tbl[encoded[e_pos] - 0x2b]) == -1) {
104 #ifdef DEBUG
105 if (encoded[e_pos] != '\x0d' && encoded[e_pos] != '\x0a') {
106 bl_debug_printf(BL_DEBUG_TAG " ignoring %c in base64\n", encoded[e_pos]);
107 }
108 #endif
109
110 if (e_len <= e_pos + 1) {
111 goto end;
112 }
113 } else {
114 count++;
115 }
116 }
117
118 decoded[d_pos++] = (((bytes[0] << 2) & 0xfc) | ((bytes[1] >> 4) & 0x3));
119
120 if (bytes[2] != -2) {
121 decoded[d_pos++] = (((bytes[1] << 4) & 0xf0) | ((bytes[2] >> 2) & 0xf));
122 } else {
123 break;
124 }
125
126 if (bytes[3] != -2) {
127 decoded[d_pos++] = (((bytes[2] << 6) & 0xc0) | (bytes[3] & 0x3f));
128 } else {
129 break;
130 }
131 }
132
133 end:
134 #ifdef DEBUG
135 decoded[d_pos] = '\0';
136 if (strlen(encoded) < 1000) {
137 bl_debug_printf(BL_DEBUG_TAG " Base64 Decode %s => %s\n", encoded, decoded);
138 }
139 #endif
140
141 return d_pos;
142 }
143
bl_hls_to_rgb(int * r,int * g,int * b,int h,int l,int s)144 void bl_hls_to_rgb(int *r, int *g, int *b,
145 int h /* 0-360 */, int l /* 0-100 */, int s /* 0-100 */) {
146 if (s == 0) {
147 *r = *g = *b = l * 255 / 100;
148 } else {
149 u_int32_t m1;
150 u_int32_t m2;
151
152 if (l < 50) {
153 m2 = l * (100 + s);
154 } else {
155 m2 = (l + s) * 100 - l * s;
156 }
157 m1 = l * 200 - m2;
158
159 *r = get_pc(h, m1, m2) * 255 / 10000;
160 if ((h -= 120) < 0) {
161 h += 360;
162 }
163 *g = get_pc(h, m1, m2) * 255 / 10000;
164 if ((h -= 120) < 0) {
165 h += 360;
166 }
167 *b = get_pc(h, m1, m2) * 255 / 10000;
168 }
169 }
170
bl_rgb_to_hls(int * h,int * l,int * s,int r,int g,int b)171 void bl_rgb_to_hls(int *h, int *l, int *s,
172 int r /* 0-255 */, int g /* 0-255 */, int b /* 0-255 */) {
173 int max;
174 int min;
175
176 if (r > g) {
177 if (g > b) {
178 /* r > g > b */
179 max = r;
180 min = b;
181 } else {
182 min = g;
183 if (r > b) {
184 /* r > b >= g */
185 max = r;
186 } else {
187 /* b >= r > g */
188 max = b;
189 }
190 }
191 } else if (b > g) {
192 /* b > g >= r */
193 max = b;
194 min = r;
195 } else {
196 max = g;
197 if (r > b) {
198 /* g >= r > b */
199 min = b;
200 } else {
201 /* g >= b >= r */
202 min = r;
203 }
204 }
205
206 *l = (max + min) * 100 / 255 / 2;
207
208 if (max == min) {
209 /* r == g == b */
210 *h = 0;
211 *s = 0;
212 } else {
213 if (max == r) {
214 *h = 60 * (g - b) / (max - min);
215 } else if (max == g) {
216 *h = 60 * (b - r) / (max - min) + 120;
217 } else /* if (max == b) */ {
218 *h = 60 * (r - g) / (max - min) + 240;
219 }
220
221 if (*h < 0) {
222 *h += 360;
223 }
224
225 if (max + min < 255) {
226 *s = (max - min) * 100 / (max + min);
227 } else {
228 *s = (max - min) * 100 / (510 - max - min);
229 }
230 }
231 }
232
bl_get_user_name(void)233 const char *bl_get_user_name(void) {
234 char *user;
235
236 #ifdef HAVE_WINDOWS_H
237 if (!(user = getenv("USERNAME")))
238 #endif
239 {
240 if (!(user = getenv("USER"))) {
241 user = getenv("LOGNAME");
242
243 #ifdef HAVE_GETPWUID
244 if (!user) {
245 struct passwd *p;
246
247 if ((p = getpwuid(bl_getuid()))) {
248 user = p->pw_name;
249 }
250 }
251 #endif
252 }
253 }
254
255 return user;
256 }
257