GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/colors.c
Date: 2025-09-22 22:57:09
Exec Total Coverage
Lines: 82 542 15.1%
Functions: 8 44 18.2%
Branches: 27 127 21.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28 #include "gate/graphics/colors.h"
29 #include "gate/strings.h"
30 #include "gate/mathematics.h"
31
32 ✗ void gate_color_set_opaque(gate_color_t* dest, gate_color_t const* src)
33 {
34 ✗ dest->rgba = src->rgba;
35 ✗ dest->a = 255;
36 ✗ }
37 687 void gate_color_set_transparent(gate_color_t* dest, gate_color_t const* src)
38 {
39 687 dest->r = (gate_uint8_t)((((int)dest->r * (int)(255 - src->a) + (int)src->r * (int)src->a)) / (255 * 2));
40 687 dest->g = (gate_uint8_t)((((int)dest->r * (int)(255 - src->a) + (int)src->r * (int)src->a)) / (255 * 2));
41 687 dest->b = (gate_uint8_t)((((int)dest->r * (int)(255 - src->a) + (int)src->r * (int)src->a)) / (255 * 2));
42 687 dest->a = (gate_uint8_t)(((int)dest->a + (int)src->a) / 2);
43 687 }
44
45 1 gate_size_t gate_color_parse_hex(gate_char8_t const* text, gate_size_t textlen, gate_color_t* col)
46 {
47 1 gate_size_t ret = 0;
48 gate_uint8_t nibbles[8];
49 gate_size_t cnt;
50 do
51 {
52
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((textlen == 0) || (text == NULL))
53 {
54 break;
55 }
56
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (text[0] == '#')
58 {
59 /* ignore hashtag */
60 ✗ ++ret;
61 ✗ ++text;
62 ✗ --textlen;
63 }
64
65
3/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1 times.
7 for (cnt = 0; (cnt < 8) && (textlen != 0); ++cnt)
66 {
67
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!gate_str_parse_hex_nibble(*text, &nibbles[cnt]))
68 {
69 ✗ break;
70 }
71 6 ++ret;
72 6 ++text;
73 6 --textlen;
74 }
75
1/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 switch (cnt)
76 {
77 ✗ case 3:
78 {
79 ✗ col->r = nibbles[0] * 17;
80 ✗ col->g = nibbles[1] * 17;
81 ✗ col->b = nibbles[2] * 17;
82 ✗ col->a = 255;
83 ✗ break;
84 }
85 ✗ case 4:
86 {
87 ✗ col->r = nibbles[0] * 17;
88 ✗ col->g = nibbles[1] * 17;
89 ✗ col->b = nibbles[2] * 17;
90 ✗ col->a = nibbles[3] * 17;
91 ✗ break;
92 }
93 1 case 6:
94 {
95 1 col->r = nibbles[0] * 16 + nibbles[1];
96 1 col->g = nibbles[2] * 16 + nibbles[3];
97 1 col->b = nibbles[4] * 16 + nibbles[5];
98 1 col->a = 255;
99 1 break;
100 }
101 ✗ case 8:
102 {
103 ✗ col->r = nibbles[0] * 16 + nibbles[1];
104 ✗ col->g = nibbles[2] * 16 + nibbles[3];
105 ✗ col->b = nibbles[4] * 16 + nibbles[5];
106 ✗ col->a = nibbles[6] * 16 + nibbles[7];
107 ✗ break;
108 }
109 ✗ default:
110 {
111 ✗ ret = 0;
112 ✗ break;
113 }
114 }
115
116 ✗ } while (0);
117 1 return ret;
118 }
119
120 1 gate_size_t gate_color_palette_rgb4_create(gate_color_rgb_t palette[16])
121 {
122 1 gate_color_rgb_t* ptr = &palette[0];
123
124 /* VGA colors */
125 1 ptr->r = 0x00; ptr->g = 0x00; ptr->b = 0x00; ++ptr; /* 00 black */
126 1 ptr->r = 0x00; ptr->g = 0x00; ptr->b = 0xaa; ++ptr; /* 01 blue */
127 1 ptr->r = 0x00; ptr->g = 0xaa; ptr->b = 0x00; ++ptr; /* 02 green */
128 1 ptr->r = 0x00; ptr->g = 0xaa; ptr->b = 0xaa; ++ptr; /* 03 cyan */
129 1 ptr->r = 0xaa; ptr->g = 0x00; ptr->b = 0x00; ++ptr; /* 04 red */
130 1 ptr->r = 0xaa; ptr->g = 0x00; ptr->b = 0xaa; ++ptr; /* 05 magenta*/
131 1 ptr->r = 0xaa; ptr->g = 0xaa; ptr->b = 0x00; ++ptr; /* 06 brown */
132 1 ptr->r = 0xaa; ptr->g = 0xaa; ptr->b = 0xaa; ++ptr; /* 07 light gray */
133 1 ptr->r = 0x55; ptr->g = 0x55; ptr->b = 0x55; ++ptr; /* 08 gray */
134 1 ptr->r = 0x55; ptr->g = 0x55; ptr->b = 0xff; ++ptr; /* 09 light blue */
135 1 ptr->r = 0x55; ptr->g = 0xff; ptr->b = 0x55; ++ptr; /* 10 light green */
136 1 ptr->r = 0x55; ptr->g = 0xff; ptr->b = 0xff; ++ptr; /* 11 light cyan */
137 1 ptr->r = 0xff; ptr->g = 0x55; ptr->b = 0x55; ++ptr; /* 12 light red */
138 1 ptr->r = 0xff; ptr->g = 0x55; ptr->b = 0xff; ++ptr; /* 13 light magenta */
139 1 ptr->r = 0xff; ptr->g = 0xff; ptr->b = 0x55; ++ptr; /* 14 yellow */
140 1 ptr->r = 0xff; ptr->g = 0xff; ptr->b = 0xff; ++ptr; /* 15 white */
141 1 return 16;
142 }
143
144 static gate_uint8_t const bi_colors[] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
145
146 static gate_color_rgb_t vga[16];
147 static volatile gate_bool_t vga_palette_initialized = false;
148
149
150 2048 gate_uint8_t gate_color_palette_rgb8_index_from_color(gate_color_rgb_t col)
151 {
152 unsigned ndx;
153 unsigned r, g, b;
154
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2047 times.
2048 if (!vga_palette_initialized)
155 {
156 1 gate_color_palette_rgb4_create(vga);
157 1 vga_palette_initialized = true;
158 }
159 /* check vga color */
160
2/2
✓ Branch 0 taken 32768 times.
✓ Branch 1 taken 2048 times.
34816 for (ndx = 0; ndx < 16; ++ndx)
161 {
162
5/6
✓ Branch 0 taken 7696 times.
✓ Branch 1 taken 25072 times.
✓ Branch 2 taken 3848 times.
✓ Branch 3 taken 3848 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3848 times.
32768 if ((vga[ndx].r == col.r) && (vga[ndx].g == col.g) && (vga[ndx].b == col.b))
163 {
164 ✗ return (gate_uint8_t)ndx;
165 }
166 }
167 /* 6*6*6 */
168 2048 r = ((unsigned)col.r + (unsigned)25) / (unsigned)51;
169 2048 g = ((unsigned)col.g + (unsigned)25) / (unsigned)51;
170 2048 b = ((unsigned)col.b + (unsigned)25) / (unsigned)51;
171 2048 return (gate_uint8_t)(16 + r * 36 + g * 6 + b);
172 }
173
174
175 ✗ void gate_color_palette_rgb8_from_index(gate_uint8_t ndx, gate_color_rgb_t* col)
176 {
177 unsigned pal_ndx;
178 ✗ if (ndx <= 15)
179 {
180 ✗ if (!vga_palette_initialized)
181 {
182 ✗ gate_color_palette_rgb4_create(vga);
183 ✗ vga_palette_initialized = true;
184 }
185 ✗ *col = vga[ndx];
186 ✗ return;
187 }
188 ✗ pal_ndx = ndx - 16;
189 ✗ if (pal_ndx < 216)
190 {
191 ✗ const gate_uint8_t r = (gate_uint8_t)(pal_ndx / 36);
192 ✗ const gate_uint8_t g = (gate_uint8_t)((pal_ndx % 36) / 6);
193 ✗ const gate_uint8_t b = (gate_uint8_t)(pal_ndx % 6);
194 ✗ col->r = bi_colors[r];
195 ✗ col->g = bi_colors[g];
196 ✗ col->b = bi_colors[b];
197 ✗ return;
198 }
199 ✗ pal_ndx -= 216;
200 ✗ if (pal_ndx < 16)
201 {
202 ✗ col->b = col->g = col->r = (gate_uint8_t)(pal_ndx * 0x11);
203 ✗ return;
204 }
205 ✗ col->r = 255;
206 ✗ col->g = 255;
207 ✗ col->b = 255;
208 }
209
210
211 ✗ gate_size_t gate_color_palette_rgb8_create(gate_color_rgb_t palette[256])
212 {
213 ✗ gate_size_t count = 0;
214 unsigned r, g, b, i;
215
216 ✗ gate_color_rgb_t* ptr = &palette[0];
217
218 /* VGA colors */
219 ✗ gate_color_palette_rgb4_create(ptr);
220 ✗ ptr += 16;
221 ✗ count += 16;
222
223 /* browser-independent 216 colors:*/
224 ✗ for (r = 0; r != sizeof(bi_colors); ++r)
225 {
226 ✗ for (g = 0; g != sizeof(bi_colors); ++g)
227 {
228 ✗ for (b = 0; b != sizeof(bi_colors); ++b)
229 {
230 ✗ ptr->r = bi_colors[r];
231 ✗ ptr->g = bi_colors[g];
232 ✗ ptr->b = bi_colors[b];
233 ✗ ++ptr;
234 ✗ ++count;
235 }
236 }
237 }
238
239 ✗ for (i = 0; i != 16; ++i)
240 {
241 ✗ ptr->b = ptr->g = ptr->r = (gate_uint8_t)(i * 0x11);
242 ✗ ++ptr;
243 ✗ ++count;
244 }
245 ✗ return count;
246 }
247
248 ✗ static int gate_color_diff(gate_color_rgb_t const* col1, gate_color_rgb_t const* col2)
249 {
250 ✗ gate_int16_t diff_r = gate_math_abs_i16((gate_int16_t)((gate_int16_t)col1->r - (gate_int16_t)col2->r));
251 ✗ gate_int16_t diff_g = gate_math_abs_i16((gate_int16_t)((gate_int16_t)col1->g - (gate_int16_t)col2->g));
252 ✗ gate_int16_t diff_b = gate_math_abs_i16((gate_int16_t)((gate_int16_t)col1->b - (gate_int16_t)col2->b));
253 ✗ return gate_math_max_i16(3, diff_r, diff_g, diff_b);
254 }
255
256
257 ✗ gate_size_t gate_color_palette_rgb8_resolve(gate_color_rgb_t find_color, gate_color_rgb_t const* palette, gate_size_t palette_length)
258 {
259 ✗ int max_diff = 255;
260 int tmp;
261 ✗ gate_size_t best_match = 0;
262 gate_size_t index;
263
264 ✗ for (index = 0; index != palette_length; ++index)
265 {
266 ✗ tmp = gate_color_diff(&find_color, &palette[index]);
267 ✗ if (tmp < max_diff)
268 {
269 ✗ best_match = index;
270 ✗ max_diff = tmp;
271 }
272 }
273 ✗ return index;
274 }
275
276 ✗ gate_size_t gate_color_load_rgb_24(gate_color_t* dest, gate_size_t pixel_count, void const* source)
277 {
278 ✗ gate_size_t cnt = 0;
279 ✗ char const* ptr = (char const*)source;
280 ✗ while (pixel_count-- != 0)
281 {
282 ✗ dest->r = *ptr;
283 ✗ ++ptr;
284 ✗ dest->g = *ptr;
285 ✗ ++ptr;
286 ✗ dest->b = *ptr;
287 ✗ ++ptr;
288 ✗ dest->a = 255;
289
290 ✗ ++dest;
291 ✗ ++cnt;
292 }
293 ✗ return cnt;
294 }
295 ✗ gate_size_t gate_color_load_rgb_32(gate_color_t* dest, gate_size_t pixel_count, void const* source)
296 {
297 ✗ gate_size_t cnt = 0;
298 ✗ char const* ptr = (char const*)source;
299 ✗ while (pixel_count-- != 0)
300 {
301 ✗ dest->r = *ptr;
302 ✗ ++ptr;
303 ✗ dest->g = *ptr;
304 ✗ ++ptr;
305 ✗ dest->b = *ptr;
306 ✗ ++ptr;
307 ✗ dest->a = *ptr;
308 ✗ ++ptr;
309
310 ✗ ++dest;
311 ✗ ++cnt;
312 }
313 ✗ return cnt;
314 }
315
316 ✗ static gate_uint8_t convert_float(gate_real32_t f)
317 {
318 ✗ int num = (int)(f * 128.0f + 127.0f);
319 ✗ if (num <= 0) return 0;
320 ✗ if (num >= 255) return 255;
321 ✗ return (gate_uint8_t)num;
322 }
323
324 ✗ static gate_real32_t convert_byte(gate_uint8_t b)
325 {
326 ✗ return (((gate_real32_t)b) - 127.0f) / 128.0f;
327 }
328
329 ✗ gate_size_t gate_color_load_yuv2_16(gate_color_t* dest, gate_size_t pixel_count, void const* source)
330 {
331 ✗ gate_size_t cnt = 0;
332 ✗ char const* ptr = (char const*)source;
333 gate_real32_t y1, u, y2, v;
334 gate_real32_t fb, fr, fg;
335
336 ✗ while (pixel_count-- != 0)
337 {
338 ✗ y1 = convert_byte(ptr[0]);
339 ✗ u = convert_byte(ptr[1]);
340 ✗ y2 = convert_byte(ptr[2]);
341 ✗ v = convert_byte(ptr[3]);
342 ✗ ptr += 4;
343
344 ✗ fb = y1 + u / 0.493f;
345 ✗ fr = y1 + v / 0.877f;
346 ✗ fg = y1 - 0.39393f * u - 0.58081f * v;
347
348 ✗ dest->r = convert_float(fr);
349 ✗ dest->g = convert_float(fg);
350 ✗ dest->b = convert_float(fb);
351 ✗ dest->a = 255;
352 ✗ ++dest;
353 ✗ ++cnt;
354
355 ✗ if (pixel_count-- != 0)
356 {
357 ✗ break;
358 }
359
360 ✗ fb = y2 + u / 0.493f;
361 ✗ fr = y2 + v / 0.877f;
362 ✗ fg = y2 - 0.39393f * u - 0.58081f * v;
363 ✗ dest->r = convert_float(fr);
364 ✗ dest->g = convert_float(fg);
365 ✗ dest->b = convert_float(fb);
366 ✗ dest->a = 255;
367 ✗ ++dest;
368 ✗ ++cnt;
369 }
370 ✗ return cnt;
371 }
372
373 ✗ gate_uint8_t gate_color_to_grayscale(gate_color_t const* src)
374 {
375 ✗ return (gate_uint8_t)((((int)src->r * 54) + ((int)src->g * 182) + ((int)src->b * 19)) / 255);
376 }
377
378 111 gate_uint8_t gate_color_to_monochrome(gate_color_t const* src, gate_uint8_t threshold)
379 {
380 gate_uint8_t gray;
381
2/4
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
111 if ((src->r == src->g) && (src->r == src->b))
382 {
383 111 gray = src->r;
384 }
385 else
386 {
387 ✗ gray = gate_color_to_grayscale(src);
388 }
389
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 60 times.
111 return (gray < threshold) ? 0 : 255;
390 }
391
392
393
394 ✗ void gate_color_convert_rgba_from_bgra_32(gate_uint8_t* rgba, gate_uint8_t const* bgra, gate_size_t pixel_count)
395 {
396 ✗ while (pixel_count-- > 0)
397 {
398 ✗ rgba[0] = bgra[2];
399 ✗ rgba[1] = bgra[1];
400 ✗ rgba[2] = bgra[0];
401 ✗ rgba[3] = bgra[3];
402 ✗ rgba += 4;
403 ✗ bgra += 4;
404 }
405 ✗ }
406 ✗ void gate_color_convert_rgba_from_bgr_24(gate_uint8_t* rgba, gate_uint8_t const* bgr24, gate_size_t pixel_count)
407 {
408 ✗ while (pixel_count-- > 0)
409 {
410 ✗ rgba[0] = bgr24[2];
411 ✗ rgba[1] = bgr24[1];
412 ✗ rgba[2] = bgr24[0];
413 ✗ rgba[3] = 255;
414 ✗ rgba += 4;
415 ✗ bgr24 += 3;
416 }
417 ✗ }
418 160 void gate_color_convert_rgba_from_rgb_24(gate_uint8_t* rgba, gate_uint8_t const* rgb24, gate_size_t pixel_count)
419 {
420
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 160 times.
10400 while (pixel_count-- > 0)
421 {
422 10240 rgba[0] = rgb24[0];
423 10240 rgba[1] = rgb24[1];
424 10240 rgba[2] = rgb24[2];
425 10240 rgba[3] = 255;
426 10240 rgba += 4;
427 10240 rgb24 += 3;
428 }
429 160 }
430 ✗ void gate_color_convert_rgba_from_rgb_16(gate_uint8_t* rgba, gate_uint8_t const* rgb565, gate_size_t pixel_count)
431 {
432 ✗ while (pixel_count-- > 0)
433 {
434 ✗ const unsigned char b = (rgb565[0] & 0x1f);
435 ✗ const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
436 ✗ const unsigned char r = (rgb565[1] & 0xf8) >> 3;
437 ✗ rgba[0] = (r << 3) | (r >> 2);
438 ✗ rgba[1] = (g << 2) | (g >> 4);
439 ✗ rgba[2] = (b << 3) | (b >> 2);
440 ✗ rgba[3] = 255;
441 ✗ rgba += 4;
442 ✗ rgb565 += 2;
443 }
444 ✗ }
445 ✗ void gate_color_convert_rgba_from_rgb_15(gate_uint8_t* rgba, gate_uint8_t const* rgb555, gate_size_t pixel_count)
446 {
447 ✗ while (pixel_count-- > 0)
448 {
449 ✗ const unsigned char b = (rgb555[0] & 0x1f);
450 ✗ const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
451 ✗ const unsigned char r = (rgb555[1] & 0x7c) >> 2;
452 ✗ rgba[0] = (r << 3) | (r >> 2);
453 ✗ rgba[1] = (g << 3) | (g >> 2);
454 ✗ rgba[2] = (b << 3) | (b >> 2);
455 ✗ rgba[3] = 255;
456 ✗ rgba += 4;
457 ✗ rgb555 += 2;
458 }
459 ✗ }
460 ✗ void gate_color_convert_rgba_from_argb_16(gate_uint8_t* rgba, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
461 {
462 ✗ while (pixel_count-- > 0)
463 {
464 ✗ const unsigned char b = (rgba4444[0] & 0x0f);
465 ✗ const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
466 ✗ const unsigned char r = (rgba4444[1] & 0x0f);
467 ✗ const unsigned char a = (rgba4444[1] & 0xf0) >> 4;
468 ✗ rgba[0] = (r << 4) | r;
469 ✗ rgba[1] = (g << 4) | g;
470 ✗ rgba[2] = (b << 4) | b;
471 ✗ rgba[3] = (a << 4) | a;
472 ✗ rgba += 4;
473 ✗ rgba4444 += 2;
474 }
475 ✗ }
476 ✗ void gate_color_convert_rgba_from_yuv2_16(gate_uint8_t* rgba, gate_uint8_t const* yuv2, gate_size_t pixel_count)
477 {
478 gate_real32_t y1, u, y2, v;
479 gate_real32_t fb, fr, fg;
480
481 ✗ for (; pixel_count >= 2; pixel_count -= 2)
482 {
483 ✗ y1 = convert_byte(yuv2[0]);
484 ✗ u = convert_byte(yuv2[1]);
485 ✗ y2 = convert_byte(yuv2[2]);
486 ✗ v = convert_byte(yuv2[3]);
487 ✗ yuv2 += 4;
488
489 ✗ fb = y1 + u / 0.493f;
490 ✗ fr = y1 + v / 0.877f;
491 ✗ fg = y1 - 0.39393f * u - 0.58081f * v;
492
493 ✗ rgba[0] = convert_float(fr);
494 ✗ rgba[1] = convert_float(fg);
495 ✗ rgba[2] = convert_float(fb);
496 ✗ rgba[3] = 255;
497 ✗ rgba += 4;
498
499 ✗ if (pixel_count-- != 0)
500 {
501 ✗ break;
502 }
503
504 ✗ fb = y2 + u / 0.493f;
505 ✗ fr = y2 + v / 0.877f;
506 ✗ fg = y2 - 0.39393f * u - 0.58081f * v;
507
508 ✗ rgba[0] = convert_float(fr);
509 ✗ rgba[1] = convert_float(fg);
510 ✗ rgba[2] = convert_float(fb);
511 ✗ rgba[3] = 255;
512 ✗ rgba += 4;
513 }
514 ✗ }
515 ✗ void gate_color_convert_rgba_from_pal_8(gate_uint8_t* rgba, gate_uint8_t const* pal8, gate_size_t pixel_count)
516 {
517 gate_color_rgb_t rgb;
518 ✗ while (pixel_count-- > 0)
519 {
520 ✗ const unsigned char c = *pal8;
521 ✗ gate_color_palette_rgb8_from_index(c, &rgb);
522 ✗ rgba[0] = rgb.r;
523 ✗ rgba[1] = rgb.g;
524 ✗ rgba[2] = rgb.b;
525 ✗ rgba[3] = 255;
526 ✗ rgba += 4;
527 ✗ ++pal8;
528 }
529 ✗ }
530 ✗ void gate_color_convert_rgba_from_gray_8(gate_uint8_t* rgba, gate_uint8_t const* gray8, gate_size_t pixel_count)
531 {
532 ✗ while (pixel_count-- > 0)
533 {
534 ✗ const unsigned char g = *gray8;
535 ✗ rgba[0] = g;
536 ✗ rgba[1] = g;
537 ✗ rgba[2] = g;
538 ✗ rgba[3] = 255;
539 ✗ rgba += 4;
540 ✗ ++gray8;
541 }
542 ✗ }
543
544
545 /**********************************************/
546
547 ✗ void gate_color_convert_rgb_from_rgba_32(gate_uint8_t* rgb, gate_uint8_t const* rgba, gate_size_t pixel_count)
548 {
549 ✗ while (pixel_count-- > 0)
550 {
551 ✗ rgb[0] = rgba[0];
552 ✗ rgb[1] = rgba[1];
553 ✗ rgb[2] = rgba[2];
554 ✗ rgb += 3;
555 ✗ rgba += 4;
556 }
557 ✗ }
558
559 ✗ void gate_color_convert_rgb_from_bgra_32(gate_uint8_t* rgb, gate_uint8_t const* bgra, gate_size_t pixel_count)
560 {
561 ✗ while (pixel_count-- > 0)
562 {
563 ✗ rgb[0] = bgra[2];
564 ✗ rgb[1] = bgra[1];
565 ✗ rgb[2] = bgra[0];
566 ✗ rgb += 3;
567 ✗ bgra += 4;
568 }
569 ✗ }
570 ✗ void gate_color_convert_rgb_from_bgr_24(gate_uint8_t* rgb, gate_uint8_t const* rgb24, gate_size_t pixel_count)
571 {
572 ✗ while (pixel_count-- > 0)
573 {
574 ✗ rgb[0] = rgb24[2];
575 ✗ rgb[1] = rgb24[1];
576 ✗ rgb[2] = rgb24[0];
577 ✗ rgb += 3;
578 ✗ rgb24 += 3;
579 }
580 ✗ }
581 32 void gate_color_convert_rgb_from_rgb_24(gate_uint8_t* rgb, gate_uint8_t const* rgb24, gate_size_t pixel_count)
582 {
583
2/2
✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 32 times.
2080 while (pixel_count-- > 0)
584 {
585 2048 rgb[0] = rgb24[0];
586 2048 rgb[1] = rgb24[1];
587 2048 rgb[2] = rgb24[2];
588 2048 rgb += 3;
589 2048 rgb24 += 3;
590 }
591 32 }
592 ✗ void gate_color_convert_rgb_from_rgb_16(gate_uint8_t* rgb, gate_uint8_t const* rgb565, gate_size_t pixel_count)
593 {
594 ✗ while (pixel_count-- > 0)
595 {
596 ✗ const unsigned char b = (rgb565[0] & 0x1f);
597 ✗ const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
598 ✗ const unsigned char r = (rgb565[1] & 0xf8) >> 3;
599 ✗ rgb[0] = (r << 3) | (r >> 2);
600 ✗ rgb[1] = (g << 2) | (g >> 4);
601 ✗ rgb[2] = (b << 3) | (b >> 2);
602 ✗ rgb += 3;
603 ✗ rgb565 += 2;
604 }
605 ✗ }
606 ✗ void gate_color_convert_rgb_from_rgb_15(gate_uint8_t* rgb, gate_uint8_t const* rgb555, gate_size_t pixel_count)
607 {
608 ✗ while (pixel_count-- > 0)
609 {
610 ✗ const unsigned char b = (rgb555[0] & 0x1f);
611 ✗ const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
612 ✗ const unsigned char r = (rgb555[1] & 0x7c) >> 2;
613 ✗ rgb[0] = (r << 3) | (r >> 2);
614 ✗ rgb[1] = (g << 3) | (g >> 2);
615 ✗ rgb[2] = (b << 3) | (b >> 2);
616 ✗ rgb += 3;
617 ✗ rgb555 += 2;
618 }
619 ✗ }
620 ✗ void gate_color_convert_rgb_from_argb_16(gate_uint8_t* rgb, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
621 {
622 ✗ while (pixel_count-- > 0)
623 {
624 ✗ const unsigned char b = (rgba4444[0] & 0x0f);
625 ✗ const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
626 ✗ const unsigned char r = (rgba4444[1] & 0x0f);
627 /*const unsigned char a = (rgba4444[1] & 0xf0) >> 4;*/
628 ✗ rgb[0] = (r << 4) | r;
629 ✗ rgb[1] = (g << 4) | g;
630 ✗ rgb[2] = (b << 4) | b;
631 ✗ rgb += 3;
632 ✗ rgba4444 += 2;
633 }
634 ✗ }
635 ✗ void gate_color_convert_rgb_from_yuv2_16(gate_uint8_t* rgb, gate_uint8_t const* yuv2, gate_size_t pixel_count)
636 {
637 gate_real32_t y1, u, y2, v;
638 gate_real32_t fb, fr, fg;
639
640 ✗ for (; pixel_count >= 2; pixel_count -= 2)
641 {
642 ✗ y1 = convert_byte(yuv2[0]);
643 ✗ u = convert_byte(yuv2[1]);
644 ✗ y2 = convert_byte(yuv2[2]);
645 ✗ v = convert_byte(yuv2[3]);
646 ✗ yuv2 += 4;
647
648 ✗ fb = y1 + u / 0.493f;
649 ✗ fr = y1 + v / 0.877f;
650 ✗ fg = y1 - 0.39393f * u - 0.58081f * v;
651
652 ✗ rgb[0] = convert_float(fr);
653 ✗ rgb[1] = convert_float(fg);
654 ✗ rgb[2] = convert_float(fb);
655 ✗ rgb += 3;
656
657 ✗ if (pixel_count-- != 0)
658 {
659 ✗ break;
660 }
661
662 ✗ fb = y2 + u / 0.493f;
663 ✗ fr = y2 + v / 0.877f;
664 ✗ fg = y2 - 0.39393f * u - 0.58081f * v;
665
666 ✗ rgb[0] = convert_float(fr);
667 ✗ rgb[1] = convert_float(fg);
668 ✗ rgb[2] = convert_float(fb);
669 ✗ rgb += 3;
670 }
671 ✗ }
672 ✗ void gate_color_convert_rgb_from_pal_8(gate_uint8_t* rgb, gate_uint8_t const* pal8, gate_size_t pixel_count)
673 {
674 gate_color_rgb_t src_rgb;
675 ✗ while (pixel_count-- > 0)
676 {
677 ✗ const unsigned char c = *pal8;
678 ✗ gate_color_palette_rgb8_from_index(c, &src_rgb);
679 ✗ rgb[0] = src_rgb.r;
680 ✗ rgb[1] = src_rgb.g;
681 ✗ rgb[2] = src_rgb.b;
682 ✗ rgb += 3;
683 ✗ ++pal8;
684 }
685 ✗ }
686 ✗ void gate_color_convert_rgb_from_gray_8(gate_uint8_t* rgb, gate_uint8_t const* gray8, gate_size_t pixel_count)
687 {
688 ✗ while (pixel_count-- > 0)
689 {
690 ✗ const unsigned char g = *gray8;
691 ✗ rgb[0] = g;
692 ✗ rgb[1] = g;
693 ✗ rgb[2] = g;
694 ✗ rgb += 3;
695 ✗ ++gray8;
696 }
697 ✗ }
698
699
700 /**********************************************/
701
702
703 ✗ void gate_color_convert_bgra_from_rgba_32(gate_uint8_t* bgra, gate_uint8_t const* rgba32, gate_size_t pixel_count)
704 {
705 ✗ while (pixel_count-- > 0)
706 {
707 ✗ bgra[0] = rgba32[2];
708 ✗ bgra[1] = rgba32[1];
709 ✗ bgra[2] = rgba32[0];
710 ✗ bgra[3] = rgba32[3];
711 ✗ bgra += 4;
712 ✗ rgba32 += 4;
713 }
714 ✗ }
715 ✗ void gate_color_convert_bgra_from_bgr_24(gate_uint8_t* bgra, gate_uint8_t const* bgr24, gate_size_t pixel_count)
716 {
717 ✗ while (pixel_count-- > 0)
718 {
719 ✗ bgra[0] = bgr24[0];
720 ✗ bgra[1] = bgr24[1];
721 ✗ bgra[2] = bgr24[2];
722 ✗ bgra[3] = 255;
723 ✗ bgra += 4;
724 ✗ bgr24 += 3;
725 }
726 ✗ }
727 32 void gate_color_convert_bgra_from_rgb_24(gate_uint8_t* bgra, gate_uint8_t const* rgb24, gate_size_t pixel_count)
728 {
729
2/2
✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 32 times.
2080 while (pixel_count-- > 0)
730 {
731 2048 bgra[0] = rgb24[2];
732 2048 bgra[1] = rgb24[1];
733 2048 bgra[2] = rgb24[0];
734 2048 bgra[3] = 255;
735 2048 bgra += 4;
736 2048 rgb24 += 3;
737 }
738 32 }
739 ✗ void gate_color_convert_bgra_from_rgb_16(gate_uint8_t* bgra, gate_uint8_t const* rgb565, gate_size_t pixel_count)
740 {
741 ✗ while (pixel_count-- > 0)
742 {
743 /* rrrrrggg gggbbbbb */
744 ✗ const unsigned char b = (rgb565[0] & 0x1f);
745 ✗ const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
746 ✗ const unsigned char r = (rgb565[1] & 0xf8) >> 3;
747 ✗ bgra[0] = (b << 3) | (b >> 2);
748 ✗ bgra[1] = (g << 2) | (g >> 4);
749 ✗ bgra[2] = (r << 3) | (r >> 2);
750 ✗ bgra[3] = 255;
751 ✗ bgra += 4;
752 ✗ rgb565 += 2;
753 }
754 ✗ }
755 ✗ void gate_color_convert_bgra_from_rgb_15(gate_uint8_t* bgra, gate_uint8_t const* rgb555, gate_size_t pixel_count)
756 {
757 ✗ while (pixel_count-- > 0)
758 {
759 /* 0rrrrrgg gggbbbbb */
760 ✗ const unsigned char b = (rgb555[0] & 0x1f);
761 ✗ const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
762 ✗ const unsigned char r = (rgb555[1] & 0x7c) >> 2;
763 ✗ bgra[0] = (b << 3) | (b >> 2);
764 ✗ bgra[1] = (g << 3) | (g >> 2);
765 ✗ bgra[2] = (r << 3) | (r >> 2);
766 ✗ bgra[3] = 255;
767 ✗ bgra += 4;
768 ✗ rgb555 += 2;
769 }
770 ✗ }
771 ✗ void gate_color_convert_bgra_from_argb_16(gate_uint8_t* bgra, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
772 {
773 ✗ while (pixel_count-- > 0)
774 {
775 /* aaaarrrrggggbbbb */
776 ✗ const unsigned char b = (rgba4444[0] & 0x0f);
777 ✗ const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
778 ✗ const unsigned char r = (rgba4444[1] & 0x0f);
779 ✗ const unsigned char a = (rgba4444[1] & 0xf0) >> 4;
780 ✗ bgra[0] = (b << 4) | b;
781 ✗ bgra[1] = (g << 4) | g;
782 ✗ bgra[2] = (r << 4) | r;
783 ✗ bgra[3] = (a << 4) | a;
784 ✗ bgra += 4;
785 ✗ rgba4444 += 2;
786 }
787 ✗ }
788 ✗ void gate_color_convert_bgra_from_yuv2_16(gate_uint8_t* bgra, gate_uint8_t const* yuv2, gate_size_t pixel_count)
789 {
790 gate_real32_t y1, u, y2, v;
791 gate_real32_t fb, fr, fg;
792
793 ✗ for (; pixel_count >= 2; pixel_count -= 2)
794 {
795 ✗ y1 = convert_byte(yuv2[0]);
796 ✗ u = convert_byte(yuv2[1]);
797 ✗ y2 = convert_byte(yuv2[2]);
798 ✗ v = convert_byte(yuv2[3]);
799 ✗ yuv2 += 4;
800
801 ✗ fb = y1 + u / 0.493f;
802 ✗ fr = y1 + v / 0.877f;
803 ✗ fg = y1 - 0.39393f * u - 0.58081f * v;
804
805 ✗ bgra[0] = convert_float(fb);
806 ✗ bgra[1] = convert_float(fg);
807 ✗ bgra[2] = convert_float(fr);
808 ✗ bgra[3] = 255;
809 ✗ bgra += 4;
810
811 ✗ if (pixel_count-- != 0)
812 {
813 ✗ break;
814 }
815
816 ✗ fb = y2 + u / 0.493f;
817 ✗ fr = y2 + v / 0.877f;
818 ✗ fg = y2 - 0.39393f * u - 0.58081f * v;
819
820 ✗ bgra[0] = convert_float(fb);
821 ✗ bgra[1] = convert_float(fg);
822 ✗ bgra[2] = convert_float(fr);
823 ✗ bgra[3] = 255;
824 ✗ bgra += 4;
825 }
826 ✗ }
827 ✗ void gate_color_convert_bgra_from_pal_8(gate_uint8_t* bgra, gate_uint8_t const* pal8, gate_size_t pixel_count)
828 {
829 gate_color_rgb_t rgb;
830 ✗ while (pixel_count-- > 0)
831 {
832 ✗ const unsigned char c = *pal8;
833 ✗ gate_color_palette_rgb8_from_index(c, &rgb);
834 ✗ bgra[0] = rgb.b;
835 ✗ bgra[1] = rgb.g;
836 ✗ bgra[2] = rgb.r;
837 ✗ bgra[3] = 255;
838 ✗ bgra += 4;
839 ✗ ++pal8;
840 }
841 ✗ }
842 ✗ void gate_color_convert_bgra_from_gray_8(gate_uint8_t* bgra, gate_uint8_t const* gray8, gate_size_t pixel_count)
843 {
844 ✗ while (pixel_count-- > 0)
845 {
846 ✗ const unsigned char g = *gray8;
847 ✗ bgra[0] = g;
848 ✗ bgra[1] = g;
849 ✗ bgra[2] = g;
850 ✗ bgra[3] = 255;
851 ✗ bgra += 4;
852 ✗ ++gray8;
853 }
854 ✗ }
855