GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/colors.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 85 542 15.7%
Functions: 8 44 18.2%
Branches: 28 127 22.0%

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 90 gate_size_t gate_color_parse_hex(gate_char8_t const* text, gate_size_t textlen, gate_color_t* col)
46 {
47 90 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 90 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 90 times.
90 if ((textlen == 0) || (text == NULL))
53 {
54 break;
55 }
56
57
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 1 times.
90 if (text[0] == '#')
58 {
59 /* ignore hashtag */
60 89 ++ret;
61 89 ++text;
62 89 --textlen;
63 }
64
65
3/4
✓ Branch 0 taken 630 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 540 times.
✓ Branch 3 taken 90 times.
630 for (cnt = 0; (cnt < 8) && (textlen != 0); ++cnt)
66 {
67
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 540 times.
540 if (!gate_str_parse_hex_nibble(*text, &nibbles[cnt]))
68 {
69 break;
70 }
71 540 ++ret;
72 540 ++text;
73 540 --textlen;
74 }
75
1/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
90 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 90 case 6:
94 {
95 90 col->r = nibbles[0] * 16 + nibbles[1];
96 90 col->g = nibbles[2] * 16 + nibbles[3];
97 90 col->b = nibbles[4] * 16 + nibbles[5];
98 90 col->a = 255;
99 90 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 90 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 gate_size_t best_match = 0;
261 gate_size_t index;
262
263 for (index = 0; index != palette_length; ++index)
264 {
265 int tmp = gate_color_diff(&find_color, &palette[index]);
266 if (tmp < max_diff)
267 {
268 best_match = index;
269 max_diff = tmp;
270 }
271 }
272 return best_match;
273 }
274
275 gate_size_t gate_color_load_rgb_24(gate_color_t* dest, gate_size_t pixel_count, void const* source)
276 {
277 gate_size_t cnt = 0;
278 char const* ptr = (char const*)source;
279 while (pixel_count-- != 0)
280 {
281 dest->r = *ptr;
282 ++ptr;
283 dest->g = *ptr;
284 ++ptr;
285 dest->b = *ptr;
286 ++ptr;
287 dest->a = 255;
288
289 ++dest;
290 ++cnt;
291 }
292 return cnt;
293 }
294 gate_size_t gate_color_load_rgb_32(gate_color_t* dest, gate_size_t pixel_count, void const* source)
295 {
296 gate_size_t cnt = 0;
297 char const* ptr = (char const*)source;
298 while (pixel_count-- != 0)
299 {
300 dest->r = *ptr;
301 ++ptr;
302 dest->g = *ptr;
303 ++ptr;
304 dest->b = *ptr;
305 ++ptr;
306 dest->a = *ptr;
307 ++ptr;
308
309 ++dest;
310 ++cnt;
311 }
312 return cnt;
313 }
314
315 static gate_uint8_t convert_float(gate_real32_t f)
316 {
317 int num = (int)(f * 128.0f + 127.0f);
318 if (num <= 0) return 0;
319 if (num >= 255) return 255;
320 return (gate_uint8_t)num;
321 }
322
323 static gate_real32_t convert_byte(gate_uint8_t b)
324 {
325 return (((gate_real32_t)b) - 127.0f) / 128.0f;
326 }
327
328 gate_size_t gate_color_load_yuv2_16(gate_color_t* dest, gate_size_t pixel_count, void const* source)
329 {
330 gate_size_t cnt = 0;
331 char const* ptr = (char const*)source;
332 gate_real32_t y1, u, y2, v;
333 gate_real32_t fb, fr, fg;
334
335 while (pixel_count-- != 0)
336 {
337 y1 = convert_byte(ptr[0]);
338 u = convert_byte(ptr[1]);
339 y2 = convert_byte(ptr[2]);
340 v = convert_byte(ptr[3]);
341 ptr += 4;
342
343 fb = y1 + u / 0.493f;
344 fr = y1 + v / 0.877f;
345 fg = y1 - 0.39393f * u - 0.58081f * v;
346
347 dest->r = convert_float(fr);
348 dest->g = convert_float(fg);
349 dest->b = convert_float(fb);
350 dest->a = 255;
351 ++dest;
352 ++cnt;
353
354 if (pixel_count-- != 0)
355 {
356 break;
357 }
358
359 fb = y2 + u / 0.493f;
360 fr = y2 + v / 0.877f;
361 fg = y2 - 0.39393f * u - 0.58081f * v;
362 dest->r = convert_float(fr);
363 dest->g = convert_float(fg);
364 dest->b = convert_float(fb);
365 dest->a = 255;
366 ++dest;
367 ++cnt;
368 }
369 return cnt;
370 }
371
372 gate_uint8_t gate_color_to_grayscale(gate_color_t const* src)
373 {
374 return (gate_uint8_t)((((int)src->r * 54) + ((int)src->g * 182) + ((int)src->b * 19)) / 255);
375 }
376
377 111 gate_uint8_t gate_color_to_monochrome(gate_color_t const* src, gate_uint8_t threshold)
378 {
379 gate_uint8_t gray;
380
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))
381 {
382 111 gray = src->r;
383 }
384 else
385 {
386 gray = gate_color_to_grayscale(src);
387 }
388
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 60 times.
111 return (gray < threshold) ? 0 : 255;
389 }
390
391
392
393 void gate_color_convert_rgba_from_bgra_32(gate_uint8_t* rgba, gate_uint8_t const* bgra, gate_size_t pixel_count)
394 {
395 while (pixel_count-- > 0)
396 {
397 rgba[0] = bgra[2];
398 rgba[1] = bgra[1];
399 rgba[2] = bgra[0];
400 rgba[3] = bgra[3];
401 rgba += 4;
402 bgra += 4;
403 }
404 }
405 void gate_color_convert_rgba_from_bgr_24(gate_uint8_t* rgba, gate_uint8_t const* bgr24, gate_size_t pixel_count)
406 {
407 while (pixel_count-- > 0)
408 {
409 rgba[0] = bgr24[2];
410 rgba[1] = bgr24[1];
411 rgba[2] = bgr24[0];
412 rgba[3] = 255;
413 rgba += 4;
414 bgr24 += 3;
415 }
416 }
417 160 void gate_color_convert_rgba_from_rgb_24(gate_uint8_t* rgba, gate_uint8_t const* rgb24, gate_size_t pixel_count)
418 {
419
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 160 times.
10400 while (pixel_count-- > 0)
420 {
421 10240 rgba[0] = rgb24[0];
422 10240 rgba[1] = rgb24[1];
423 10240 rgba[2] = rgb24[2];
424 10240 rgba[3] = 255;
425 10240 rgba += 4;
426 10240 rgb24 += 3;
427 }
428 160 }
429 void gate_color_convert_rgba_from_rgb_16(gate_uint8_t* rgba, gate_uint8_t const* rgb565, gate_size_t pixel_count)
430 {
431 while (pixel_count-- > 0)
432 {
433 const unsigned char b = (rgb565[0] & 0x1f);
434 const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
435 const unsigned char r = (rgb565[1] & 0xf8) >> 3;
436 rgba[0] = (r << 3) | (r >> 2);
437 rgba[1] = (g << 2) | (g >> 4);
438 rgba[2] = (b << 3) | (b >> 2);
439 rgba[3] = 255;
440 rgba += 4;
441 rgb565 += 2;
442 }
443 }
444 void gate_color_convert_rgba_from_rgb_15(gate_uint8_t* rgba, gate_uint8_t const* rgb555, gate_size_t pixel_count)
445 {
446 while (pixel_count-- > 0)
447 {
448 const unsigned char b = (rgb555[0] & 0x1f);
449 const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
450 const unsigned char r = (rgb555[1] & 0x7c) >> 2;
451 rgba[0] = (r << 3) | (r >> 2);
452 rgba[1] = (g << 3) | (g >> 2);
453 rgba[2] = (b << 3) | (b >> 2);
454 rgba[3] = 255;
455 rgba += 4;
456 rgb555 += 2;
457 }
458 }
459 void gate_color_convert_rgba_from_argb_16(gate_uint8_t* rgba, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
460 {
461 while (pixel_count-- > 0)
462 {
463 const unsigned char b = (rgba4444[0] & 0x0f);
464 const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
465 const unsigned char r = (rgba4444[1] & 0x0f);
466 const unsigned char a = (rgba4444[1] & 0xf0) >> 4;
467 rgba[0] = (r << 4) | r;
468 rgba[1] = (g << 4) | g;
469 rgba[2] = (b << 4) | b;
470 rgba[3] = (a << 4) | a;
471 rgba += 4;
472 rgba4444 += 2;
473 }
474 }
475 void gate_color_convert_rgba_from_yuv2_16(gate_uint8_t* rgba, gate_uint8_t const* yuv2, gate_size_t pixel_count)
476 {
477 gate_real32_t y1, u, y2, v;
478 gate_real32_t fb, fr, fg;
479
480 for (; pixel_count >= 2; pixel_count -= 2)
481 {
482 y1 = convert_byte(yuv2[0]);
483 u = convert_byte(yuv2[1]);
484 y2 = convert_byte(yuv2[2]);
485 v = convert_byte(yuv2[3]);
486 yuv2 += 4;
487
488 fb = y1 + u / 0.493f;
489 fr = y1 + v / 0.877f;
490 fg = y1 - 0.39393f * u - 0.58081f * v;
491
492 rgba[0] = convert_float(fr);
493 rgba[1] = convert_float(fg);
494 rgba[2] = convert_float(fb);
495 rgba[3] = 255;
496 rgba += 4;
497
498 if (pixel_count-- != 0)
499 {
500 break;
501 }
502
503 fb = y2 + u / 0.493f;
504 fr = y2 + v / 0.877f;
505 fg = y2 - 0.39393f * u - 0.58081f * v;
506
507 rgba[0] = convert_float(fr);
508 rgba[1] = convert_float(fg);
509 rgba[2] = convert_float(fb);
510 rgba[3] = 255;
511 rgba += 4;
512 }
513 }
514 void gate_color_convert_rgba_from_pal_8(gate_uint8_t* rgba, gate_uint8_t const* pal8, gate_size_t pixel_count)
515 {
516 gate_color_rgb_t rgb;
517 while (pixel_count-- > 0)
518 {
519 const unsigned char c = *pal8;
520 gate_color_palette_rgb8_from_index(c, &rgb);
521 rgba[0] = rgb.r;
522 rgba[1] = rgb.g;
523 rgba[2] = rgb.b;
524 rgba[3] = 255;
525 rgba += 4;
526 ++pal8;
527 }
528 }
529 void gate_color_convert_rgba_from_gray_8(gate_uint8_t* rgba, gate_uint8_t const* gray8, gate_size_t pixel_count)
530 {
531 while (pixel_count-- > 0)
532 {
533 const unsigned char g = *gray8;
534 rgba[0] = g;
535 rgba[1] = g;
536 rgba[2] = g;
537 rgba[3] = 255;
538 rgba += 4;
539 ++gray8;
540 }
541 }
542
543
544 /**********************************************/
545
546 void gate_color_convert_rgb_from_rgba_32(gate_uint8_t* rgb, gate_uint8_t const* rgba, gate_size_t pixel_count)
547 {
548 while (pixel_count-- > 0)
549 {
550 rgb[0] = rgba[0];
551 rgb[1] = rgba[1];
552 rgb[2] = rgba[2];
553 rgb += 3;
554 rgba += 4;
555 }
556 }
557
558 void gate_color_convert_rgb_from_bgra_32(gate_uint8_t* rgb, gate_uint8_t const* bgra, gate_size_t pixel_count)
559 {
560 while (pixel_count-- > 0)
561 {
562 rgb[0] = bgra[2];
563 rgb[1] = bgra[1];
564 rgb[2] = bgra[0];
565 rgb += 3;
566 bgra += 4;
567 }
568 }
569 void gate_color_convert_rgb_from_bgr_24(gate_uint8_t* rgb, gate_uint8_t const* rgb24, gate_size_t pixel_count)
570 {
571 while (pixel_count-- > 0)
572 {
573 rgb[0] = rgb24[2];
574 rgb[1] = rgb24[1];
575 rgb[2] = rgb24[0];
576 rgb += 3;
577 rgb24 += 3;
578 }
579 }
580 32 void gate_color_convert_rgb_from_rgb_24(gate_uint8_t* rgb, gate_uint8_t const* rgb24, gate_size_t pixel_count)
581 {
582
2/2
✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 32 times.
2080 while (pixel_count-- > 0)
583 {
584 2048 rgb[0] = rgb24[0];
585 2048 rgb[1] = rgb24[1];
586 2048 rgb[2] = rgb24[2];
587 2048 rgb += 3;
588 2048 rgb24 += 3;
589 }
590 32 }
591 void gate_color_convert_rgb_from_rgb_16(gate_uint8_t* rgb, gate_uint8_t const* rgb565, gate_size_t pixel_count)
592 {
593 while (pixel_count-- > 0)
594 {
595 const unsigned char b = (rgb565[0] & 0x1f);
596 const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
597 const unsigned char r = (rgb565[1] & 0xf8) >> 3;
598 rgb[0] = (r << 3) | (r >> 2);
599 rgb[1] = (g << 2) | (g >> 4);
600 rgb[2] = (b << 3) | (b >> 2);
601 rgb += 3;
602 rgb565 += 2;
603 }
604 }
605 void gate_color_convert_rgb_from_rgb_15(gate_uint8_t* rgb, gate_uint8_t const* rgb555, gate_size_t pixel_count)
606 {
607 while (pixel_count-- > 0)
608 {
609 const unsigned char b = (rgb555[0] & 0x1f);
610 const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
611 const unsigned char r = (rgb555[1] & 0x7c) >> 2;
612 rgb[0] = (r << 3) | (r >> 2);
613 rgb[1] = (g << 3) | (g >> 2);
614 rgb[2] = (b << 3) | (b >> 2);
615 rgb += 3;
616 rgb555 += 2;
617 }
618 }
619 void gate_color_convert_rgb_from_argb_16(gate_uint8_t* rgb, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
620 {
621 while (pixel_count-- > 0)
622 {
623 const unsigned char b = (rgba4444[0] & 0x0f);
624 const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
625 const unsigned char r = (rgba4444[1] & 0x0f);
626 /*const unsigned char a = (rgba4444[1] & 0xf0) >> 4;*/
627 rgb[0] = (r << 4) | r;
628 rgb[1] = (g << 4) | g;
629 rgb[2] = (b << 4) | b;
630 rgb += 3;
631 rgba4444 += 2;
632 }
633 }
634 void gate_color_convert_rgb_from_yuv2_16(gate_uint8_t* rgb, gate_uint8_t const* yuv2, gate_size_t pixel_count)
635 {
636 gate_real32_t y1, u, y2, v;
637 gate_real32_t fb, fr, fg;
638
639 for (; pixel_count >= 2; pixel_count -= 2)
640 {
641 y1 = convert_byte(yuv2[0]);
642 u = convert_byte(yuv2[1]);
643 y2 = convert_byte(yuv2[2]);
644 v = convert_byte(yuv2[3]);
645 yuv2 += 4;
646
647 fb = y1 + u / 0.493f;
648 fr = y1 + v / 0.877f;
649 fg = y1 - 0.39393f * u - 0.58081f * v;
650
651 rgb[0] = convert_float(fr);
652 rgb[1] = convert_float(fg);
653 rgb[2] = convert_float(fb);
654 rgb += 3;
655
656 if (pixel_count-- != 0)
657 {
658 break;
659 }
660
661 fb = y2 + u / 0.493f;
662 fr = y2 + v / 0.877f;
663 fg = y2 - 0.39393f * u - 0.58081f * v;
664
665 rgb[0] = convert_float(fr);
666 rgb[1] = convert_float(fg);
667 rgb[2] = convert_float(fb);
668 rgb += 3;
669 }
670 }
671 void gate_color_convert_rgb_from_pal_8(gate_uint8_t* rgb, gate_uint8_t const* pal8, gate_size_t pixel_count)
672 {
673 gate_color_rgb_t src_rgb;
674 while (pixel_count-- > 0)
675 {
676 const unsigned char c = *pal8;
677 gate_color_palette_rgb8_from_index(c, &src_rgb);
678 rgb[0] = src_rgb.r;
679 rgb[1] = src_rgb.g;
680 rgb[2] = src_rgb.b;
681 rgb += 3;
682 ++pal8;
683 }
684 }
685 void gate_color_convert_rgb_from_gray_8(gate_uint8_t* rgb, gate_uint8_t const* gray8, gate_size_t pixel_count)
686 {
687 while (pixel_count-- > 0)
688 {
689 const unsigned char g = *gray8;
690 rgb[0] = g;
691 rgb[1] = g;
692 rgb[2] = g;
693 rgb += 3;
694 ++gray8;
695 }
696 }
697
698
699 /**********************************************/
700
701
702 void gate_color_convert_bgra_from_rgba_32(gate_uint8_t* bgra, gate_uint8_t const* rgba32, gate_size_t pixel_count)
703 {
704 while (pixel_count-- > 0)
705 {
706 bgra[0] = rgba32[2];
707 bgra[1] = rgba32[1];
708 bgra[2] = rgba32[0];
709 bgra[3] = rgba32[3];
710 bgra += 4;
711 rgba32 += 4;
712 }
713 }
714 void gate_color_convert_bgra_from_bgr_24(gate_uint8_t* bgra, gate_uint8_t const* bgr24, gate_size_t pixel_count)
715 {
716 while (pixel_count-- > 0)
717 {
718 bgra[0] = bgr24[0];
719 bgra[1] = bgr24[1];
720 bgra[2] = bgr24[2];
721 bgra[3] = 255;
722 bgra += 4;
723 bgr24 += 3;
724 }
725 }
726 32 void gate_color_convert_bgra_from_rgb_24(gate_uint8_t* bgra, gate_uint8_t const* rgb24, gate_size_t pixel_count)
727 {
728
2/2
✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 32 times.
2080 while (pixel_count-- > 0)
729 {
730 2048 bgra[0] = rgb24[2];
731 2048 bgra[1] = rgb24[1];
732 2048 bgra[2] = rgb24[0];
733 2048 bgra[3] = 255;
734 2048 bgra += 4;
735 2048 rgb24 += 3;
736 }
737 32 }
738 void gate_color_convert_bgra_from_rgb_16(gate_uint8_t* bgra, gate_uint8_t const* rgb565, gate_size_t pixel_count)
739 {
740 while (pixel_count-- > 0)
741 {
742 /* rrrrrggg gggbbbbb */
743 const unsigned char b = (rgb565[0] & 0x1f);
744 const unsigned char g = ((rgb565[1] & 0x07) << 3) | ((rgb565[0] & 0xe0) >> 5);
745 const unsigned char r = (rgb565[1] & 0xf8) >> 3;
746 bgra[0] = (b << 3) | (b >> 2);
747 bgra[1] = (g << 2) | (g >> 4);
748 bgra[2] = (r << 3) | (r >> 2);
749 bgra[3] = 255;
750 bgra += 4;
751 rgb565 += 2;
752 }
753 }
754 void gate_color_convert_bgra_from_rgb_15(gate_uint8_t* bgra, gate_uint8_t const* rgb555, gate_size_t pixel_count)
755 {
756 while (pixel_count-- > 0)
757 {
758 /* 0rrrrrgg gggbbbbb */
759 const unsigned char b = (rgb555[0] & 0x1f);
760 const unsigned char g = ((rgb555[1] & 0x03) << 3) | ((rgb555[0] & 0xe0) >> 5);
761 const unsigned char r = (rgb555[1] & 0x7c) >> 2;
762 bgra[0] = (b << 3) | (b >> 2);
763 bgra[1] = (g << 3) | (g >> 2);
764 bgra[2] = (r << 3) | (r >> 2);
765 bgra[3] = 255;
766 bgra += 4;
767 rgb555 += 2;
768 }
769 }
770 void gate_color_convert_bgra_from_argb_16(gate_uint8_t* bgra, gate_uint8_t const* rgba4444, gate_size_t pixel_count)
771 {
772 while (pixel_count-- > 0)
773 {
774 /* aaaarrrrggggbbbb */
775 const unsigned char b = (rgba4444[0] & 0x0f);
776 const unsigned char g = (rgba4444[0] & 0xf0) >> 4;
777 const unsigned char r = (rgba4444[1] & 0x0f);
778 const unsigned char a = (rgba4444[1] & 0xf0) >> 4;
779 bgra[0] = (b << 4) | b;
780 bgra[1] = (g << 4) | g;
781 bgra[2] = (r << 4) | r;
782 bgra[3] = (a << 4) | a;
783 bgra += 4;
784 rgba4444 += 2;
785 }
786 }
787 void gate_color_convert_bgra_from_yuv2_16(gate_uint8_t* bgra, gate_uint8_t const* yuv2, gate_size_t pixel_count)
788 {
789 gate_real32_t y1, u, y2, v;
790 gate_real32_t fb, fr, fg;
791
792 for (; pixel_count >= 2; pixel_count -= 2)
793 {
794 y1 = convert_byte(yuv2[0]);
795 u = convert_byte(yuv2[1]);
796 y2 = convert_byte(yuv2[2]);
797 v = convert_byte(yuv2[3]);
798 yuv2 += 4;
799
800 fb = y1 + u / 0.493f;
801 fr = y1 + v / 0.877f;
802 fg = y1 - 0.39393f * u - 0.58081f * v;
803
804 bgra[0] = convert_float(fb);
805 bgra[1] = convert_float(fg);
806 bgra[2] = convert_float(fr);
807 bgra[3] = 255;
808 bgra += 4;
809
810 if (pixel_count-- != 0)
811 {
812 break;
813 }
814
815 fb = y2 + u / 0.493f;
816 fr = y2 + v / 0.877f;
817 fg = y2 - 0.39393f * u - 0.58081f * v;
818
819 bgra[0] = convert_float(fb);
820 bgra[1] = convert_float(fg);
821 bgra[2] = convert_float(fr);
822 bgra[3] = 255;
823 bgra += 4;
824 }
825 }
826 void gate_color_convert_bgra_from_pal_8(gate_uint8_t* bgra, gate_uint8_t const* pal8, gate_size_t pixel_count)
827 {
828 gate_color_rgb_t rgb;
829 while (pixel_count-- > 0)
830 {
831 const unsigned char c = *pal8;
832 gate_color_palette_rgb8_from_index(c, &rgb);
833 bgra[0] = rgb.b;
834 bgra[1] = rgb.g;
835 bgra[2] = rgb.r;
836 bgra[3] = 255;
837 bgra += 4;
838 ++pal8;
839 }
840 }
841 void gate_color_convert_bgra_from_gray_8(gate_uint8_t* bgra, gate_uint8_t const* gray8, gate_size_t pixel_count)
842 {
843 while (pixel_count-- > 0)
844 {
845 const unsigned char g = *gray8;
846 bgra[0] = g;
847 bgra[1] = g;
848 bgra[2] = g;
849 bgra[3] = 255;
850 bgra += 4;
851 ++gray8;
852 }
853 }
854