picofuse

color.h
Go to the documentation of this file.
1 
6 #pragma once
7 #include <stdint.h>
8 
17 typedef uint32_t pix_color_t;
18 
25 #define PIX_COLOR_NONE 0x00000000u
26 
36 #define PIX_COLOR_RED 0xFF0000FFu
37 #define PIX_COLOR_GREEN 0x00FF00FFu
38 #define PIX_COLOR_BLUE 0x0000FFFFu
39 #define PIX_COLOR_WHITE 0xFFFFFFFFu
40 #define PIX_COLOR_BLACK 0x000000FFu
41 
46 #define PIX_COLOR_RGBA(r, g, b, a) \
47  ((pix_color_t)(((uint32_t)(uint8_t)(r) << 24) | \
48  ((uint32_t)(uint8_t)(g) << 16) | \
49  ((uint32_t)(uint8_t)(b) << 8) | \
50  (uint32_t)(uint8_t)(a)))
51 
56 #define PIX_COLOR_RGB(r, g, b) PIX_COLOR_RGBA(r, g, b, 0xFFu)
57 
62 static inline uint8_t pix_color_r(pix_color_t color) {
63  return (uint8_t)(color >> 24);
64 }
65 
70 static inline uint8_t pix_color_g(pix_color_t color) {
71  return (uint8_t)(color >> 16);
72 }
73 
78 static inline uint8_t pix_color_b(pix_color_t color) {
79  return (uint8_t)(color >> 8);
80 }
81 
86 static inline uint8_t pix_color_a(pix_color_t color) {
87  return (uint8_t)color;
88 }
89 
100  uint32_t sa = pix_color_a(src);
101  uint32_t da = pix_color_a(dst);
102  uint32_t ia = 255u - sa;
103 
104  // dst's RGB must be weighted by dst's own alpha too - a partially
105  // transparent dst shouldn't contribute its raw RGB at full strength, the
106  // same way its own draw would only have partially covered whatever was
107  // beneath it. The result is then un-premultiplied by the composited
108  // alpha, since pix_color_t stores straight (not premultiplied) RGB.
109  uint32_t out_a = sa + (da * ia + 127u) / 255u;
110  if (out_a == 0) {
111  return PIX_COLOR_NONE;
112  }
113 
114  uint32_t denom = out_a * 255u;
115  uint32_t half = denom / 2u;
116  uint8_t r = (uint8_t)((pix_color_r(src) * sa * 255u +
117  pix_color_r(dst) * da * ia + half) / denom);
118  uint8_t g = (uint8_t)((pix_color_g(src) * sa * 255u +
119  pix_color_g(dst) * da * ia + half) / denom);
120  uint8_t b = (uint8_t)((pix_color_b(src) * sa * 255u +
121  pix_color_b(dst) * da * ia + half) / denom);
122  return PIX_COLOR_RGBA(r, g, b, (uint8_t)out_a);
123 }
static uint8_t pix_color_b(pix_color_t color)
Extract the blue channel.
Definition: color.h:78
static uint8_t pix_color_a(pix_color_t color)
Extract the alpha channel.
Definition: color.h:86
uint32_t pix_color_t
Color value type for pixel operations.
Definition: color.h:17
static uint8_t pix_color_r(pix_color_t color)
Extract the red channel.
Definition: color.h:62
#define PIX_COLOR_NONE
Fully transparent (all channels zero) - a "no color" sentinel, distinct from the opaque PIX_COLOR_BLA...
Definition: color.h:25
#define PIX_COLOR_RGBA(r, g, b, a)
Construct a pix_color_t from separate R/G/B/A components.
Definition: color.h:46
static pix_color_t pix_color_blend(pix_color_t src, pix_color_t dst)
Alpha-composite src over dst ("over" compositing).
Definition: color.h:99
static uint8_t pix_color_g(pix_color_t color)
Extract the green channel.
Definition: color.h:70