1#ifndef PIXELOPERATIONS_HH
2#define PIXELOPERATIONS_HH
10using Pixel = uint32_t;
22 [[nodiscard]]
unsigned red(
Pixel p)
const;
24 [[nodiscard]]
unsigned blue(
Pixel p)
const;
29 [[nodiscard]]
Pixel combine(
unsigned r,
unsigned g,
unsigned b)
const;
35 template<
unsigned w1,
unsigned w2>
37 template<
unsigned w1,
unsigned w2,
unsigned w3>
39 template<
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
41 template<
unsigned w1,
unsigned w2,
unsigned w3,
42 unsigned w4,
unsigned w5,
unsigned w6>
46 template<
unsigned w1,
unsigned w2>
47 [[nodiscard]]
Pixel blend(std::span<const Pixel, 2> p)
const;
48 template<
unsigned w1,
unsigned w2,
unsigned w3>
49 [[nodiscard]]
Pixel blend(std::span<const Pixel, 3> p)
const;
50 template<
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
51 [[nodiscard]]
Pixel blend(std::span<const Pixel, 4> p)
const;
52 template<
unsigned w1,
unsigned w2,
unsigned w3,
53 unsigned w4,
unsigned w5,
unsigned w6>
54 [[nodiscard]]
Pixel blend(std::span<const Pixel, 6> p)
const;
90 return (p >> 0) & 0xFF;
94 return (p >> 8) & 0xFF;
98 return (p >> 16) & 0xFF;
102 return (p >> 24) & 0xFF;
106 unsigned r,
unsigned g,
unsigned b)
const
108 return Pixel((r << 0) | (
g << 8) | (b << 16) | (0xFF << 24));
116 return (p1 & p2) + (((p1 ^ p2) & 0xFEFEFEFE) >> 1);
122 return (p1 | p2) - (((p1 ^ p2) & 0xFEFEFEFE) >> 1);
125template<
unsigned w1,
unsigned w2>
128 constexpr unsigned total = w1 + w2;
129 if constexpr (w1 == 0) {
131 }
else if constexpr (w1 > w2) {
132 return blend<w2, w1>(p2, p1);
134 }
else if constexpr (w1 == w2) {
136 return avgDown(p1, p2);
137 }
else if constexpr ((3 * w1) == w2) {
139 Pixel p11 = avgDown(p1, p2);
140 return avgUp(p11, p2);
141 }
else if constexpr ((7 * w1) == w2) {
143 Pixel p11 = avgDown(p1, p2);
144 Pixel p13 = avgDown(p11, p2);
145 return avgUp(p13, p2);
146 }
else if constexpr ((5 * w1) == (3 * w2)) {
148 Pixel p11 = avgUp (p1, p2);
149 Pixel p13 = avgDown(p11, p2);
150 return avgDown(p11, p13);
152 }
else if constexpr (!std::has_single_bit(total)) {
156 constexpr unsigned newTotal = 256;
157 constexpr unsigned ww1 = (2 * w1 * newTotal + total) / (2 * total);
158 constexpr unsigned ww2 = 256 - ww1;
159 return blend<ww1, ww2>(p1, p2);
163 constexpr unsigned l2 = std::bit_width(total) - 1;
164 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
165 (p2 & 0x00FF00FF) * w2
166 ) >> l2) & 0x00FF00FF;
167 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
168 ((p2 & 0xFF00FF00) >> l2) * w2
174template<
unsigned w1,
unsigned w2,
unsigned w3>
177 constexpr unsigned total = w1 + w2 +
w3;
178 if constexpr (std::has_single_bit(total)) {
179 constexpr unsigned l2 = std::bit_width(total) - 1;
180 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
181 (p2 & 0x00FF00FF) * w2 +
182 (
p3 & 0x00FF00FF) *
w3) >> l2) & 0x00FF00FF;
183 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
184 ((p2 & 0xFF00FF00) >> l2) * w2 +
185 ((
p3 & 0xFF00FF00) >> l2) *
w3) & 0xFF00FF00;
188 unsigned r = (
red (p1) * w1 +
red (p2) * w2 +
red (
p3) *
w3) / total;
195template<
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
199 constexpr unsigned total = w1 + w2 +
w3 +
w4;
200 if constexpr (std::has_single_bit(total)) {
201 constexpr unsigned l2 = std::bit_width(total) - 1;
202 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
203 (p2 & 0x00FF00FF) * w2 +
204 (
p3 & 0x00FF00FF) *
w3 +
205 (
p4 & 0x00FF00FF) *
w4) >> l2) & 0x00FF00FF;
206 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
207 ((p2 & 0xFF00FF00) >> l2) * w2 +
208 ((
p3 & 0xFF00FF00) >> l2) *
w3 +
209 ((
p4 & 0xFF00FF00) >> l2) *
w4) & 0xFF00FF00;
212 unsigned r = (
red (p1) * w1 +
red (p2) * w2 +
216 unsigned b = (
blue (p1) * w1 +
blue (p2) * w2 +
222template<
unsigned w1,
unsigned w2,
unsigned w3,
223 unsigned w4,
unsigned w5,
unsigned w6>
227 constexpr unsigned total = w1 + w2 +
w3 +
w4 + w5 + w6;
228 if constexpr (std::has_single_bit(total)) {
229 constexpr unsigned l2 = std::bit_width(total) - 1;
230 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
231 (p2 & 0x00FF00FF) * w2 +
232 (
p3 & 0x00FF00FF) *
w3 +
233 (
p4 & 0x00FF00FF) *
w4 +
234 (p5 & 0x00FF00FF) * w5 +
235 (p6 & 0x00FF00FF) * w6) >> l2) & 0x00FF00FF;
236 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
237 ((p2 & 0xFF00FF00) >> l2) * w2 +
238 ((
p3 & 0xFF00FF00) >> l2) *
w3 +
239 ((
p4 & 0xFF00FF00) >> l2) *
w4 +
240 ((p5 & 0xFF00FF00) >> l2) * w5 +
241 ((p6 & 0xFF00FF00) >> l2) * w6) & 0xFF00FF00;
244 unsigned r = (
red (p1) * w1 +
red (p2) * w2 +
246 red (p5) * w5 +
red (p6) * w6) / total;
250 unsigned b = (
blue (p1) * w1 +
blue (p2) * w2 +
252 blue (p5) * w5 +
blue (p6) * w6) / total;
258template<
unsigned w1,
unsigned w2>
261 return blend<w1, w2>(p[0], p[1]);
264template<
unsigned w1,
unsigned w2,
unsigned w3>
267 return blend<w1, w2, w3>(p[0], p[1], p[2]);
270template<
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
273 return blend<w1, w2, w3, w4>(p[0], p[1], p[2], p[3]);
276template<
unsigned w1,
unsigned w2,
unsigned w3,
277 unsigned w4,
unsigned w5,
unsigned w6>
280 return blend<w1, w2, w3, w4, w5, w6>(p[0], p[1], p[2], p[3], p[4], p[5]);
285 return ((((p & 0x00FF00FF) * x) & 0xFF00FF00) >> 8)
286 | ((((p >> 8) & 0x00FF00FF) * x) & 0xFF00FF00);
292 unsigned rb1 = (p1 >> 0) & 0x00FF00FF;
293 unsigned ag1 = (p1 >> 8) & 0x00FF00FF;
294 unsigned rb2 = (p2 >> 0) & 0x00FF00FF;
295 unsigned ag2 = (p2 >> 8) & 0x00FF00FF;
300 unsigned trb = ((rb2 - rb1) * x) >> 8;
301 unsigned tag = ((ag2 - ag1) * x) >> 0;
303 unsigned rb = ((trb + rb1) << 0) & 0x00FF00FF;
304 unsigned ag = (tag + (ag1 << 8)) & 0xFF00FF00;
311 unsigned a =
alpha(p1);
314 return lerp(p2, p1, a);
Pixel lerp(Pixel p1, Pixel p2, unsigned x) const
Perform linear interpolation between two pixels.
Pixel blend(Pixel p1, Pixel p2) const
Blend the given colors into a single color.
unsigned green(Pixel p) const
Pixel combine(unsigned r, unsigned g, unsigned b) const
Combine RGB components to a pixel.
unsigned alpha(Pixel p) const
static Pixel multiply(Pixel p, unsigned x)
Perform a component wise multiplication of a pixel with an 8-bit fractional value: result = (pixel * ...
Pixel alphaBlend(Pixel p1, Pixel p2) const
Perform alpha blending of two pixels.
unsigned red(Pixel p) const
Extract RGBA components, each in range [0..255].
unsigned blue(Pixel p) const
mat4 p4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 0, 7, 8), vec4(7, 8, 9, 0))
mat3 p3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 0, 9))
This file implemented 3 utility functions:
CharacterConverter::Pixel Pixel