GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/colors.c
Date: 2025-09-14 13:10:38
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 /*
121 static gate_size_t add_patch_color(gate_color_rgb_t* ptr, gate_uint8_t value)
122 {
123 ptr->r = value; ptr->g = 0; ptr->b = 0;
124 ++ptr;
125 ptr->r = 0; ptr->g = value; ptr->b = 0;
126 ++ptr;
127 ptr->r = 0; ptr->g = 0; ptr->b = value;
128 ++ptr;
129 ptr->r = value; ptr->g = value; ptr->b = 0;
130 ++ptr;
131 ptr->r = value; ptr->g = 0; ptr->b = value;
132 ++ptr;
133 ptr->r = 0; ptr->g = value; ptr->b = value;
134 ++ptr;
135 return 6;
136 }
137 */
138
139 1 gate_size_t gate_color_palette_rgb4_create(gate_color_rgb_t palette[16])
140 {
141 1 gate_color_rgb_t* ptr = &palette[0];
142
143 /* VGA colors */
144 1 ptr->r = 0x00; ptr->g = 0x00; ptr->b = 0x00; ++ptr; /* 00 black */
145 1 ptr->r = 0x00; ptr->g = 0x00; ptr->b = 0xaa; ++ptr; /* 01 blue */
146 1 ptr->r = 0x00; ptr->g = 0xaa; ptr->b = 0x00; ++ptr; /* 02 green */
147 1 ptr->r = 0x00; ptr->g = 0xaa; ptr->b = 0xaa; ++ptr; /* 03 cyan */
148 1 ptr->r = 0xaa; ptr->g = 0x00; ptr->b = 0x00; ++ptr; /* 04 red */
149 1 ptr->r = 0xaa; ptr->g = 0x00; ptr->b = 0xaa; ++ptr; /* 05 magenta*/
150 1 ptr->r = 0xaa; ptr->g = 0xaa; ptr->b = 0x00; ++ptr; /* 06 brown */
151 1 ptr->r = 0xaa; ptr->g = 0xaa; ptr->b = 0xaa; ++ptr; /* 07 light gray */
152 1 ptr->r = 0x55; ptr->g = 0x55; ptr->b = 0x55; ++ptr; /* 08 gray */
153 1 ptr->r = 0x55; ptr->g = 0x55; ptr->b = 0xff; ++ptr; /* 09 light blue */
154 1 ptr->r = 0x55; ptr->g = 0xff; ptr->b = 0x55; ++ptr; /* 10 light green */
155 1 ptr->r = 0x55; ptr->g = 0xff; ptr->b = 0xff; ++ptr; /* 11 light cyan */
156 1 ptr->r = 0xff; ptr->g = 0x55; ptr->b = 0x55; ++ptr; /* 12 light red */
157 1 ptr->r = 0xff; ptr->g = 0x55; ptr->b = 0xff; ++ptr; /* 13 light magenta */
158 1 ptr->r = 0xff; ptr->g = 0xff; ptr->b = 0x55; ++ptr; /* 14 yellow */
159 1 ptr->r = 0xff; ptr->g = 0xff; ptr->b = 0xff; ++ptr; /* 15 white */
160 1 return 16;
161 }
162
163 static gate_uint8_t const bi_colors[] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
164
165 static gate_color_rgb_t vga[16];
166 static volatile gate_bool_t vga_palette_initialized = false;
167
168
169 2048 gate_uint8_t gate_color_palette_rgb8_index_from_color(gate_color_rgb_t col)
170 {
171 unsigned ndx;
172 unsigned r, g, b;
173
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2047 times.
2048 if (!vga_palette_initialized)
174 {
175 1 gate_color_palette_rgb4_create(vga);
176 1 vga_palette_initialized = true;
177 }
178 /* check vga color */
179
2/2
✓ Branch 0 taken 32768 times.
✓ Branch 1 taken 2048 times.
34816 for (ndx = 0; ndx < 16; ++ndx)
180 {
181
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))
182 {
183 return (gate_uint8_t)ndx;
184 }
185 }
186 /* 6*6*6 */
187 2048 r = ((unsigned)col.r + (unsigned)25) / (unsigned)51;
188 2048 g = ((unsigned)col.g + (unsigned)25) / (unsigned)51;
189 2048 b = ((unsigned)col.b + (unsigned)25) / (unsigned)51;
190 2048 return (gate_uint8_t)(16 + r * 36 + g * 6 + b);
191 }
192
193
194 void gate_color_palette_rgb8_from_index(gate_uint8_t ndx, gate_color_rgb_t* col)
195 {
196 unsigned pal_ndx;
197 if (ndx <= 15)
198 {
199 if (!vga_palette_initialized)
200 {
201 gate_color_palette_rgb4_create(vga);
202 vga_palette_initialized = true;
203 }
204 *col = vga[ndx];
205 return;
206 }
207 pal_ndx = ndx - 16;
208 if (pal_ndx < 216)
209 {
210 const gate_uint8_t r = (gate_uint8_t)(pal_ndx / 36);
211 const gate_uint8_t g = (gate_uint8_t)((pal_ndx % 36) / 6);
212 const gate_uint8_t b = (gate_uint8_t)(pal_ndx % 6);
213 col->r = bi_colors[r];
214 col->g = bi_colors[g];
215 col->b = bi_colors[b];
216 return;
217 }
218 pal_ndx -= 216;
219 if (pal_ndx < 16)
220 {
221 col->b = col->g = col->r = (gate_uint8_t)(pal_ndx * 0x11);
222 return;
223 }
224 col->r = 255;
225 col->g = 255;
226 col->b = 255;
227 }
228
229
230 gate_size_t gate_color_palette_rgb8_create(gate_color_rgb_t palette[256])
231 {
232 gate_size_t count = 0;
233 unsigned r, g, b, i;
234
235 gate_color_rgb_t* ptr = &palette[0];
236
237 /* VGA colors */
238 gate_color_palette_rgb4_create(ptr);
239 ptr += 16;
240 count += 16;
241
242 /* browser-independent 216 colors:*/
243 for (r = 0; r != sizeof(bi_colors); ++r)
244 {
245 for (g = 0; g != sizeof(bi_colors); ++g)
246 {
247 for (b = 0; b != sizeof(bi_colors); ++b)
248 {
249 ptr->r = bi_colors[r];
250 ptr->g = bi_colors[g];
251 ptr->b = bi_colors[b];
252 ++ptr;
253 ++count;
254 }
255 }
256 }
257
258 for (i = 0; i != 16; ++i)
259 {
260 ptr->b = ptr->g = ptr->r = (gate_uint8_t)(i * 0x11);
261 ++ptr;
262 ++count;
263 }
264 return count;
265 }
266
267 static int gate_color_diff(gate_color_rgb_t const* col1, gate_color_rgb_t const* col2)
268 {
269 gate_int16_t diff_r = gate_math_abs_i16((gate_int16_t)((gate_int16_t)col1->r - (gate_int16_t)col2->r));
270 gate_int16_t diff_g = gate_math_abs_i16((gate_int16_t)((gate_int16_t)col1->g - (gate_int16_t)col2->g));
271 gate_int16_t diff_b = gate_math_abs_i16((gate_int16_t)((gate_int16_t)col1->b - (gate_int16_t)col2->b));
272 return gate_math_max_i16(3, diff_r, diff_g, diff_b);
273 }
274
275
276 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)
277 {
278 int max_diff = 255;
279 int tmp;
280 gate_size_t best_match = 0;
281 gate_size_t index;
282
283 for (index = 0; index != palette_length; ++index)
284 {
285 tmp = gate_color_diff(&find_color, &palette[index]);
286 if (tmp < max_diff)
287 {
288 best_match = index;
289 max_diff = tmp;
290 }
291 }
292 return index;
293 }
294
295 gate_size_t gate_color_load_rgb_24(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 = 255;
308
309 ++dest;
310 ++cnt;
311 }
312 return cnt;
313 }
314 gate_size_t gate_color_load_rgb_32(gate_color_t* dest, gate_size_t pixel_count, void const* source)
315 {
316 gate_size_t cnt = 0;
317 char const* ptr = (char const*)source;
318 while (pixel_count-- != 0)
319 {
320 dest->r = *ptr;
321 ++ptr;
322 dest->g = *ptr;
323 ++ptr;
324 dest->b = *ptr;
325 ++ptr;
326 dest->a = *ptr;
327 ++ptr;
328
329 ++dest;
330 ++cnt;
331 }
332 return cnt;
333 }
334
335 static gate_uint8_t convert_float(gate_real32_t f)
336 {
337 int num = (int)(f * 128.0f + 127.0f);
338 if (num <= 0) return 0;
339 if (num >= 255) return 255;
340 return (gate_uint8_t)num;
341 }
342
343 static gate_real32_t convert_byte(gate_uint8_t b)
344 {
345 return (((gate_real32_t)b) - 127.0f) / 128.0f;
346 }
347
348 gate_size_t gate_color_load_yuv2_16(gate_color_t* dest, gate_size_t pixel_count, void const* source)
349 {
350 gate_size_t cnt = 0;
351 char const* ptr = (char const*)source;
352 gate_real32_t y1, u, y2, v;
353 gate_real32_t fb, fr, fg;
354
355 while (pixel_count-- != 0)
356 {
357 y1 = convert_byte(ptr[0]);
358 u = convert_byte(ptr[1]);
359 y2 = convert_byte(ptr[2]);
360 v = convert_byte(ptr[3]);
361 ptr += 4;
362
363 fb = y1 + u / 0.493f;
364 fr = y1 + v / 0.877f;
365 fg = y1 - 0.39393f * u - 0.58081f * v;
366
367 dest->r = convert_float(fr);
368 dest->g = convert_float(fg);
369 dest->b = convert_float(fb);
370 dest->a = 255;
371 ++dest;
372 ++cnt;
373
374 if (pixel_count-- != 0)
375 {
376 break;
377 }
378
379 fb = y2 + u / 0.493f;
380 fr = y2 + v / 0.877f;
381 fg = y2 - 0.39393f * u - 0.58081f * v;
382 dest->r = convert_float(fr);
383 dest->g = convert_float(fg);
384 dest->b = convert_float(fb);
385 dest->a = 255;
386 ++dest;
387 ++cnt;
388 }
389 return cnt;
390 }
391
392 gate_uint8_t gate_color_to_grayscale(gate_color_t const* src)
393 {
394 return (gate_uint8_t)((((int)src->r * 54) + ((int)src->g * 182) + ((int)src->b * 19)) / 255);
395 }
396
397 111 gate_uint8_t gate_color_to_monochrome(gate_color_t const* src, gate_uint8_t threshold)
398 {
399 gate_uint8_t gray;
400
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))
401 {
402 111 gray = src->r;
403 }
404 else
405 {
406 gray = gate_color_to_grayscale(src);
407 }
408
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 60 times.
111 return (gray < threshold) ? 0 : 255;
409 }
410
411
412
413 void gate_color_convert_rgba_from_bgra_32(gate_uint8_t* rgba, gate_uint8_t const* bgra, gate_size_t pixel_count)
414 {
415 while (pixel_count-- > 0)
416 {
417 rgba[0] = bgra[2];
418 rgba[1] = bgra[1];
419 rgba[2] = bgra[0];
420 rgba[3] = bgra[3];
421 rgba += 4;
422 bgra += 4;
423 }
424 }
425 void gate_color_convert_rgba_from_bgr_24(gate_uint8_t* rgba, gate_uint8_t const* bgr24, gate_size_t pixel_count)
426 {
427 while (pixel_count-- > 0)
428 {
429 rgba[0] = bgr24[2];
430 rgba[1] = bgr24[1];
431 rgba[2] = bgr24[0];
432 rgba[3] = 255;
433 rgba += 4;
434 bgr24 += 3;
435 }
436 }
437 160 void gate_color_convert_rgba_from_rgb_24(gate_uint8_t* rgba, gate_uint8_t const* rgb24, gate_size_t pixel_count)
438 {
439
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 160 times.
10400 while (pixel_count-- > 0)
440 {
441 10240 rgba[0] = rgb24[0];
442 10240 rgba[1] = rgb24[1];
443 10240 rgba[2] = rgb24[2];
444 10240 rgba[3] = 255;
445 10240 rgba += 4;
446 10240 rgb24 += 3;
447 }
448 160 }
449 void gate_color_convert_rgba_from_rgb_16(gate_uint8_t* rgba, gate_uint8_t const* rgb565, gate_size_t pixel_count)
450 {
451 while (pixel_count-- > 0)
452 {
453 const unsigned char b = (rgb565[0] & 0x1f);
454 const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
455 const unsigned char r = (rgb565[1] & 0xf8) >> 3;
456 rgba[0] = (r << 3) | (r >> 2);
457 rgba[1] = (g << 2) | (g >> 4);
458 rgba[2] = (b << 3) | (b >> 2);
459 rgba[3] = 255;
460 rgba += 4;
461 rgb565 += 2;
462 }
463 }
464 void gate_color_convert_rgba_from_rgb_15(gate_uint8_t* rgba, gate_uint8_t const* rgb555, gate_size_t pixel_count)
465 {
466 while (pixel_count-- > 0)
467 {
468 const unsigned char b = (rgb555[0] & 0x1f);
469 const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
470 const unsigned char r = (rgb555[1] & 0x7c) >> 2;
471 rgba[0] = (r << 3) | (r >> 2);
472 rgba[1] = (g << 3) | (g >> 2);
473 rgba[2] = (b << 3) | (b >> 2);
474 rgba[3] = 255;
475 rgba += 4;
476 rgb555 += 2;
477 }
478 }
479 void gate_color_convert_rgba_from_argb_16(gate_uint8_t* rgba, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
480 {
481 while (pixel_count-- > 0)
482 {
483 const unsigned char b = (rgba4444[0] & 0x0f);
484 const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
485 const unsigned char r = (rgba4444[1] & 0x0f);
486 const unsigned char a = (rgba4444[1] & 0xf0) >> 4;
487 rgba[0] = (r << 4) | r;
488 rgba[1] = (g << 4) | g;
489 rgba[2] = (b << 4) | b;
490 rgba[3] = (a << 4) | a;
491 rgba += 4;
492 rgba4444 += 2;
493 }
494 }
495 void gate_color_convert_rgba_from_yuv2_16(gate_uint8_t* rgba, gate_uint8_t const* yuv2, gate_size_t pixel_count)
496 {
497 gate_real32_t y1, u, y2, v;
498 gate_real32_t fb, fr, fg;
499
500 for (; pixel_count >= 2; pixel_count -= 2)
501 {
502 y1 = convert_byte(yuv2[0]);
503 u = convert_byte(yuv2[1]);
504 y2 = convert_byte(yuv2[2]);
505 v = convert_byte(yuv2[3]);
506 yuv2 += 4;
507
508 fb = y1 + u / 0.493f;
509 fr = y1 + v / 0.877f;
510 fg = y1 - 0.39393f * u - 0.58081f * v;
511
512 rgba[0] = convert_float(fr);
513 rgba[1] = convert_float(fg);
514 rgba[2] = convert_float(fb);
515 rgba[3] = 255;
516 rgba += 4;
517
518 if (pixel_count-- != 0)
519 {
520 break;
521 }
522
523 fb = y2 + u / 0.493f;
524 fr = y2 + v / 0.877f;
525 fg = y2 - 0.39393f * u - 0.58081f * v;
526
527 rgba[0] = convert_float(fr);
528 rgba[1] = convert_float(fg);
529 rgba[2] = convert_float(fb);
530 rgba[3] = 255;
531 rgba += 4;
532 }
533 }
534 void gate_color_convert_rgba_from_pal_8(gate_uint8_t* rgba, gate_uint8_t const* pal8, gate_size_t pixel_count)
535 {
536 gate_color_rgb_t rgb;
537 while (pixel_count-- > 0)
538 {
539 const unsigned char c = *pal8;
540 gate_color_palette_rgb8_from_index(c, &rgb);
541 rgba[0] = rgb.r;
542 rgba[1] = rgb.g;
543 rgba[2] = rgb.b;
544 rgba[3] = 255;
545 rgba += 4;
546 ++pal8;
547 }
548 }
549 void gate_color_convert_rgba_from_gray_8(gate_uint8_t* rgba, gate_uint8_t const* gray8, gate_size_t pixel_count)
550 {
551 while (pixel_count-- > 0)
552 {
553 const unsigned char g = *gray8;
554 rgba[0] = g;
555 rgba[1] = g;
556 rgba[2] = g;
557 rgba[3] = 255;
558 rgba += 4;
559 ++gray8;
560 }
561 }
562
563
564 /**********************************************/
565
566 void gate_color_convert_rgb_from_rgba_32(gate_uint8_t* rgb, gate_uint8_t const* rgba, gate_size_t pixel_count)
567 {
568 while (pixel_count-- > 0)
569 {
570 rgb[0] = rgba[0];
571 rgb[1] = rgba[1];
572 rgb[2] = rgba[2];
573 rgb += 3;
574 rgba += 4;
575 }
576 }
577
578 void gate_color_convert_rgb_from_bgra_32(gate_uint8_t* rgb, gate_uint8_t const* bgra, gate_size_t pixel_count)
579 {
580 while (pixel_count-- > 0)
581 {
582 rgb[0] = bgra[2];
583 rgb[1] = bgra[1];
584 rgb[2] = bgra[0];
585 rgb += 3;
586 bgra += 4;
587 }
588 }
589 void gate_color_convert_rgb_from_bgr_24(gate_uint8_t* rgb, gate_uint8_t const* rgb24, gate_size_t pixel_count)
590 {
591 while (pixel_count-- > 0)
592 {
593 rgb[0] = rgb24[2];
594 rgb[1] = rgb24[1];
595 rgb[2] = rgb24[0];
596 rgb += 3;
597 rgb24 += 3;
598 }
599 }
600 32 void gate_color_convert_rgb_from_rgb_24(gate_uint8_t* rgb, gate_uint8_t const* rgb24, gate_size_t pixel_count)
601 {
602
2/2
✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 32 times.
2080 while (pixel_count-- > 0)
603 {
604 2048 rgb[0] = rgb24[0];
605 2048 rgb[1] = rgb24[1];
606 2048 rgb[2] = rgb24[2];
607 2048 rgb += 3;
608 2048 rgb24 += 3;
609 }
610 32 }
611 void gate_color_convert_rgb_from_rgb_16(gate_uint8_t* rgb, gate_uint8_t const* rgb565, gate_size_t pixel_count)
612 {
613 while (pixel_count-- > 0)
614 {
615 const unsigned char b = (rgb565[0] & 0x1f);
616 const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
617 const unsigned char r = (rgb565[1] & 0xf8) >> 3;
618 rgb[0] = (r << 3) | (r >> 2);
619 rgb[1] = (g << 2) | (g >> 4);
620 rgb[2] = (b << 3) | (b >> 2);
621 rgb += 3;
622 rgb565 += 2;
623 }
624 }
625 void gate_color_convert_rgb_from_rgb_15(gate_uint8_t* rgb, gate_uint8_t const* rgb555, gate_size_t pixel_count)
626 {
627 while (pixel_count-- > 0)
628 {
629 const unsigned char b = (rgb555[0] & 0x1f);
630 const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
631 const unsigned char r = (rgb555[1] & 0x7c) >> 2;
632 rgb[0] = (r << 3) | (r >> 2);
633 rgb[1] = (g << 3) | (g >> 2);
634 rgb[2] = (b << 3) | (b >> 2);
635 rgb += 3;
636 rgb555 += 2;
637 }
638 }
639 void gate_color_convert_rgb_from_argb_16(gate_uint8_t* rgb, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
640 {
641 while (pixel_count-- > 0)
642 {
643 const unsigned char b = (rgba4444[0] & 0x0f);
644 const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
645 const unsigned char r = (rgba4444[1] & 0x0f);
646 /*const unsigned char a = (rgba4444[1] & 0xf0) >> 4;*/
647 rgb[0] = (r << 4) | r;
648 rgb[1] = (g << 4) | g;
649 rgb[2] = (b << 4) | b;
650 rgb += 3;
651 rgba4444 += 2;
652 }
653 }
654 void gate_color_convert_rgb_from_yuv2_16(gate_uint8_t* rgb, gate_uint8_t const* yuv2, gate_size_t pixel_count)
655 {
656 gate_real32_t y1, u, y2, v;
657 gate_real32_t fb, fr, fg;
658
659 for (; pixel_count >= 2; pixel_count -= 2)
660 {
661 y1 = convert_byte(yuv2[0]);
662 u = convert_byte(yuv2[1]);
663 y2 = convert_byte(yuv2[2]);
664 v = convert_byte(yuv2[3]);
665 yuv2 += 4;
666
667 fb = y1 + u / 0.493f;
668 fr = y1 + v / 0.877f;
669 fg = y1 - 0.39393f * u - 0.58081f * v;
670
671 rgb[0] = convert_float(fr);
672 rgb[1] = convert_float(fg);
673 rgb[2] = convert_float(fb);
674 rgb += 3;
675
676 if (pixel_count-- != 0)
677 {
678 break;
679 }
680
681 fb = y2 + u / 0.493f;
682 fr = y2 + v / 0.877f;
683 fg = y2 - 0.39393f * u - 0.58081f * v;
684
685 rgb[0] = convert_float(fr);
686 rgb[1] = convert_float(fg);
687 rgb[2] = convert_float(fb);
688 rgb += 3;
689 }
690 }
691 void gate_color_convert_rgb_from_pal_8(gate_uint8_t* rgb, gate_uint8_t const* pal8, gate_size_t pixel_count)
692 {
693 gate_color_rgb_t src_rgb;
694 while (pixel_count-- > 0)
695 {
696 const unsigned char c = *pal8;
697 gate_color_palette_rgb8_from_index(c, &src_rgb);
698 rgb[0] = src_rgb.r;
699 rgb[1] = src_rgb.g;
700 rgb[2] = src_rgb.b;
701 rgb += 3;
702 ++pal8;
703 }
704 }
705 void gate_color_convert_rgb_from_gray_8(gate_uint8_t* rgb, gate_uint8_t const* gray8, gate_size_t pixel_count)
706 {
707 while (pixel_count-- > 0)
708 {
709 const unsigned char g = *gray8;
710 rgb[0] = g;
711 rgb[1] = g;
712 rgb[2] = g;
713 rgb += 3;
714 ++gray8;
715 }
716 }
717
718
719 /**********************************************/
720
721
722 void gate_color_convert_bgra_from_rgba_32(gate_uint8_t* bgra, gate_uint8_t const* rgba32, gate_size_t pixel_count)
723 {
724 while (pixel_count-- > 0)
725 {
726 bgra[0] = rgba32[2];
727 bgra[1] = rgba32[1];
728 bgra[2] = rgba32[0];
729 bgra[3] = rgba32[3];
730 bgra += 4;
731 rgba32 += 4;
732 }
733 }
734 void gate_color_convert_bgra_from_bgr_24(gate_uint8_t* bgra, gate_uint8_t const* bgr24, gate_size_t pixel_count)
735 {
736 while (pixel_count-- > 0)
737 {
738 bgra[0] = bgr24[0];
739 bgra[1] = bgr24[1];
740 bgra[2] = bgr24[2];
741 bgra[3] = 255;
742 bgra += 4;
743 bgr24 += 3;
744 }
745 }
746 32 void gate_color_convert_bgra_from_rgb_24(gate_uint8_t* bgra, gate_uint8_t const* rgb24, gate_size_t pixel_count)
747 {
748
2/2
✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 32 times.
2080 while (pixel_count-- > 0)
749 {
750 2048 bgra[0] = rgb24[2];
751 2048 bgra[1] = rgb24[1];
752 2048 bgra[2] = rgb24[0];
753 2048 bgra[3] = 255;
754 2048 bgra += 4;
755 2048 rgb24 += 3;
756 }
757 32 }
758 void gate_color_convert_bgra_from_rgb_16(gate_uint8_t* bgra, gate_uint8_t const* rgb565, gate_size_t pixel_count)
759 {
760 while (pixel_count-- > 0)
761 {
762 /* rrrrrggg gggbbbbb */
763 const unsigned char b = (rgb565[0] & 0x1f);
764 const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
765 const unsigned char r = (rgb565[1] & 0xf8) >> 3;
766 bgra[0] = (b << 3) | (b >> 2);
767 bgra[1] = (g << 2) | (g >> 4);
768 bgra[2] = (r << 3) | (r >> 2);
769 bgra[3] = 255;
770 bgra += 4;
771 rgb565 += 2;
772 }
773 }
774 void gate_color_convert_bgra_from_rgb_15(gate_uint8_t* bgra, gate_uint8_t const* rgb555, gate_size_t pixel_count)
775 {
776 while (pixel_count-- > 0)
777 {
778 /* 0rrrrrgg gggbbbbb */
779 const unsigned char b = (rgb555[0] & 0x1f);
780 const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
781 const unsigned char r = (rgb555[1] & 0x7c) >> 2;
782 bgra[0] = (b << 3) | (b >> 2);
783 bgra[1] = (g << 3) | (g >> 2);
784 bgra[2] = (r << 3) | (r >> 2);
785 bgra[3] = 255;
786 bgra += 4;
787 rgb555 += 2;
788 }
789 }
790 void gate_color_convert_bgra_from_argb_16(gate_uint8_t* bgra, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
791 {
792 while (pixel_count-- > 0)
793 {
794 /* aaaarrrrggggbbbb */
795 const unsigned char b = (rgba4444[0] & 0x0f);
796 const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
797 const unsigned char r = (rgba4444[1] & 0x0f);
798 const unsigned char a = (rgba4444[1] & 0xf0) >> 4;
799 bgra[0] = (b << 4) | b;
800 bgra[1] = (g << 4) | g;
801 bgra[2] = (r << 4) | r;
802 bgra[3] = (a << 4) | a;
803 bgra += 4;
804 rgba4444 += 2;
805 }
806 }
807 void gate_color_convert_bgra_from_yuv2_16(gate_uint8_t* bgra, gate_uint8_t const* yuv2, gate_size_t pixel_count)
808 {
809 gate_real32_t y1, u, y2, v;
810 gate_real32_t fb, fr, fg;
811
812 for (; pixel_count >= 2; pixel_count -= 2)
813 {
814 y1 = convert_byte(yuv2[0]);
815 u = convert_byte(yuv2[1]);
816 y2 = convert_byte(yuv2[2]);
817 v = convert_byte(yuv2[3]);
818 yuv2 += 4;
819
820 fb = y1 + u / 0.493f;
821 fr = y1 + v / 0.877f;
822 fg = y1 - 0.39393f * u - 0.58081f * v;
823
824 bgra[0] = convert_float(fb);
825 bgra[1] = convert_float(fg);
826 bgra[2] = convert_float(fr);
827 bgra[3] = 255;
828 bgra += 4;
829
830 if (pixel_count-- != 0)
831 {
832 break;
833 }
834
835 fb = y2 + u / 0.493f;
836 fr = y2 + v / 0.877f;
837 fg = y2 - 0.39393f * u - 0.58081f * v;
838
839 bgra[0] = convert_float(fb);
840 bgra[1] = convert_float(fg);
841 bgra[2] = convert_float(fr);
842 bgra[3] = 255;
843 bgra += 4;
844 }
845 }
846 void gate_color_convert_bgra_from_pal_8(gate_uint8_t* bgra, gate_uint8_t const* pal8, gate_size_t pixel_count)
847 {
848 gate_color_rgb_t rgb;
849 while (pixel_count-- > 0)
850 {
851 const unsigned char c = *pal8;
852 gate_color_palette_rgb8_from_index(c, &rgb);
853 bgra[0] = rgb.b;
854 bgra[1] = rgb.g;
855 bgra[2] = rgb.r;
856 bgra[3] = 255;
857 bgra += 4;
858 ++pal8;
859 }
860 }
861 void gate_color_convert_bgra_from_gray_8(gate_uint8_t* bgra, gate_uint8_t const* gray8, gate_size_t pixel_count)
862 {
863 while (pixel_count-- > 0)
864 {
865 const unsigned char g = *gray8;
866 bgra[0] = g;
867 bgra[1] = g;
868 bgra[2] = g;
869 bgra[3] = 255;
870 bgra += 4;
871 ++gray8;
872 }
873 }
874