1#![allow(non_snake_case)]
8
9use crate::*;
10
11pub trait Blend {
12 fn blend(src: u32, dst: u32) -> u32;
13}
14
15pub struct Dst;
16
17impl Blend for Dst {
18 #[inline]
19 fn blend(_src: u32, dst: u32) -> u32 {
20 dst
21 }
22}
23
24pub struct Src;
25
26impl Blend for Src {
27 #[inline]
28 fn blend(src: u32, _dst: u32) -> u32 {
29 src
30 }
31}
32
33pub struct Clear;
34
35impl Blend for Clear {
36 #[inline]
37 fn blend(_src: u32, _dst: u32) -> u32 {
38 0
39 }
40}
41
42pub struct SrcOver;
43
44impl Blend for SrcOver {
45 #[inline]
46 fn blend(src: u32, dst: u32) -> u32 {
47 over(src, dst)
48 }
49}
50
51pub struct DstOver;
52
53impl Blend for DstOver {
54 #[inline]
55 fn blend(src: u32, dst: u32) -> u32 {
56 over(dst, src)
57 }
58}
59
60pub struct SrcIn;
61
62impl Blend for SrcIn {
63 #[inline]
64 fn blend(src: u32, dst: u32) -> u32 {
65 alpha_mul(src, alpha_to_alpha256(packed_alpha(dst)))
66 }
67}
68
69pub struct DstIn;
70
71impl Blend for DstIn {
72 #[inline]
73 fn blend(src: u32, dst: u32) -> u32 {
74 alpha_mul(dst, alpha_to_alpha256(packed_alpha(src)))
75 }
76}
77
78pub struct SrcOut;
79
80impl Blend for SrcOut {
81 #[inline]
82 fn blend(src: u32, dst: u32) -> u32 {
83 alpha_mul(src, alpha_to_alpha256(255 - packed_alpha(dst)))
84 }
85}
86
87pub struct DstOut;
88
89impl Blend for DstOut {
90 #[inline]
91 fn blend(src: u32, dst: u32) -> u32 {
92 alpha_mul(dst, alpha_to_alpha256(255 - packed_alpha(src)))
93 }
94}
95
96pub struct SrcAtop;
97
98impl Blend for SrcAtop {
99 #[inline]
100 fn blend(src: u32, dst: u32) -> u32 {
101 let sa = packed_alpha(src);
102 let da = packed_alpha(dst);
103 let isa = 255 - sa;
104
105 pack_argb32(
106 da,
107 muldiv255(da, get_packed_r32(src)) + muldiv255(isa, get_packed_r32(dst)),
108 muldiv255(da, get_packed_g32(src)) + muldiv255(isa, get_packed_g32(dst)),
109 muldiv255(da, get_packed_b32(src)) + muldiv255(isa, get_packed_b32(dst))
110 )
111 }
112}
113
114pub struct DstAtop;
115
116impl Blend for DstAtop {
117 #[inline]
118 fn blend(src: u32, dst: u32) -> u32 {
119 let sa = packed_alpha(src);
120 let da = packed_alpha(dst);
121 let ida = 255 - da;
122
123 pack_argb32(
124 sa,
125 muldiv255(ida, get_packed_r32(src)) + muldiv255(sa, get_packed_r32(dst)),
126 muldiv255(ida, get_packed_g32(src)) + muldiv255(sa, get_packed_g32(dst)),
127 muldiv255(ida, get_packed_b32(src)) + muldiv255(sa, get_packed_b32(dst))
128 )
129 }
130}
131
132pub struct Xor;
133
134impl Blend for Xor {
135 #[inline]
136 fn blend(src: u32, dst: u32) -> u32 {
137 let sa = packed_alpha(src);
138 let da = packed_alpha(dst);
139 let isa = 255 - sa;
140 let ida = 255 - da;
141
142 pack_argb32(
143 sa + da - (muldiv255(sa, da) * 2),
144 muldiv255(ida, get_packed_r32(src)) + muldiv255(isa, get_packed_r32(dst)),
145 muldiv255(ida, get_packed_g32(src)) + muldiv255(isa, get_packed_g32(dst)),
146 muldiv255(ida, get_packed_b32(src)) + muldiv255(isa, get_packed_b32(dst))
147 )
148 }
149}
150
151fn saturated_add(a: u32, b: u32) -> u32 {
152 debug_assert!(a <= 255);
153 debug_assert!(b <= 255);
154 let sum = a + b;
155 if sum > 255 {
156 255
157 } else {
158 sum
159 }
160}
161
162pub struct Add;
163
164impl Blend for Add {
165 #[inline]
166 fn blend(src: u32, dst: u32) -> u32 {
167 pack_argb32(
168 saturated_add(get_packed_a32(src), get_packed_a32(dst)),
169 saturated_add(get_packed_r32(src), get_packed_r32(dst)),
170 saturated_add(get_packed_g32(src), get_packed_g32(dst)),
171 saturated_add(get_packed_b32(src), get_packed_b32(dst))
172 )
173 }
174}
175
176fn blendfunc_multiply_byte(sc: i32, dc: i32, sa: i32, da: i32) -> u32 {
180 clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc)
181}
182
183pub struct Multiply;
184
185impl Blend for Multiply {
186 fn blend(src: u32, dst: u32) -> u32 {
187 let sa = get_packed_a32(src) as i32;
188 let da = get_packed_a32(dst) as i32;
189 pack_argb32(
190 srcover_byte(get_packed_a32(src), get_packed_a32(dst)),
191 blendfunc_multiply_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
192 blendfunc_multiply_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
193 blendfunc_multiply_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
194 )
195 }
196}
197
198#[inline]
199fn srcover_byte(a: u32, b: u32) -> u32 {
200 a + b - muldiv255(a, b)
201}
202
203pub struct Screen;
204
205impl Blend for Screen {
206 #[inline]
207 fn blend(src: u32, dst: u32) -> u32 {
208 pack_argb32(
209 srcover_byte(get_packed_a32(src), get_packed_a32(dst)),
210 srcover_byte(get_packed_r32(src), get_packed_r32(dst)),
211 srcover_byte(get_packed_g32(src), get_packed_g32(dst)),
212 srcover_byte(get_packed_b32(src), get_packed_b32(dst))
213 )
214 }
215}
216
217fn clamp_div255round(prod: i32) -> u32 {
218 if prod <= 0 {
219 0
220 } else if prod >= 255 * 255 {
221 255
222 } else {
223 div255(prod as u32)
224 }
225}
226
227fn overlay_byte(sc: u32, dc: u32, sa: u32, da: u32) -> u32 {
228 let tmp = sc * (255 - da) + dc * (255 - sa);
229 let rc;
230 if 2 * dc <= da {
231 rc = 2 * sc * dc;
232 } else {
233 rc = sa * da - 2 * (da - dc) * (sa - sc);
234 }
235 clamp_div255round((rc + tmp) as i32)
236}
237
238pub struct Overlay;
239
240impl Blend for Overlay {
241 fn blend(src: u32, dst: u32) -> u32 {
242 let sa = get_packed_a32(src);
243 let da = get_packed_a32(dst);
244 pack_argb32(
245 srcover_byte(sa, da),
246 overlay_byte(get_packed_r32(src), get_packed_r32(dst), sa, da),
247 overlay_byte(get_packed_g32(src), get_packed_g32(dst), sa, da),
248 overlay_byte(get_packed_b32(src), get_packed_b32(dst), sa, da)
249 )
250 }
251}
252
253fn darken_byte(sc: u32, dc: u32, sa: u32, da: u32) -> u32 {
254 let sd = sc * da;
255 let ds = dc * sa;
256 if sd < ds {
257 sc + dc - div255(ds)
259 } else {
260 dc + sc - div255(sd)
262 }
263}
264
265pub struct Darken;
266
267impl Blend for Darken {
268 fn blend(src: u32, dst: u32) -> u32 {
269 let sa = get_packed_a32(src);
270 let da = get_packed_a32(dst);
271 pack_argb32(
272 srcover_byte(sa, da),
273 darken_byte(get_packed_r32(src), get_packed_r32(dst), sa, da),
274 darken_byte(get_packed_g32(src), get_packed_g32(dst), sa, da),
275 darken_byte(get_packed_b32(src), get_packed_b32(dst), sa, da)
276 )
277 }
278}
279
280fn lighten_byte(sc: u32, dc: u32, sa: u32, da: u32) -> u32 {
281 let sd = sc * da;
282 let ds = dc * sa;
283 if sd > ds {
284 sc + dc - div255(ds)
286 } else {
287 dc + sc - div255(sd)
289 }
290}
291
292pub struct Lighten;
293
294impl Blend for Lighten {
295 fn blend(src: u32, dst: u32) -> u32 {
296 let sa = get_packed_a32(src);
297 let da = get_packed_a32(dst);
298 pack_argb32(
299 srcover_byte(sa, da),
300 lighten_byte(get_packed_r32(src), get_packed_r32(dst), sa, da),
301 lighten_byte(get_packed_g32(src), get_packed_g32(dst), sa, da),
302 lighten_byte(get_packed_b32(src), get_packed_b32(dst), sa, da)
303 )
304 }
305}
306
307fn colordodge_byte(sc: i32, dc: i32, sa: i32, da: i32) -> u32 {
308 let mut diff = sa - sc;
309 let rc = if 0 == dc {
310 return muldiv255(sc as u32, (255 - da) as u32);
311 } else if 0 == diff {
312 sa * da + sc * (255 - da) + dc * (255 - sa)
313 } else {
314 diff = (dc * sa) / diff;
315 sa * (if da < diff { da } else { diff }) + sc * (255 - da) + dc * (255 - sa)
316 };
317 clamp_div255round(rc)
318}
319
320pub struct ColorDodge;
321
322impl Blend for ColorDodge {
323 fn blend(src: u32, dst: u32) -> u32 {
324 let sa = get_packed_a32(src) as i32;
325 let da = get_packed_a32(dst) as i32;
326 pack_argb32(
327 srcover_byte(sa as u32, da as u32),
328 colordodge_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
329 colordodge_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
330 colordodge_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
331 )
332 }
333}
334
335fn colorburn_byte(sc: i32, dc: i32, sa: i32, da: i32) -> u32 {
336 let rc = if dc == da {
337 sa * da + sc * (255 - da) + dc * (255 - sa)
338 } else if 0 == sc {
339 return muldiv255(dc as u32, (255 - sa) as u32);
340 } else {
341 let tmp = (da - dc) * sa / sc;
342 sa * (da - (if da < tmp { da } else { tmp }))
343 + sc * (255 - da) + dc * (255 - sa)
344 };
345 clamp_div255round(rc)
346}
347
348pub struct ColorBurn;
349
350impl Blend for ColorBurn {
351 fn blend(src: u32, dst: u32) -> u32 {
352 let sa = get_packed_a32(src) as i32;
353 let da = get_packed_a32(dst) as i32;
354 pack_argb32(
355 srcover_byte(sa as u32, da as u32),
356 colorburn_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
357 colorburn_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
358 colorburn_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
359 )
360 }
361}
362
363fn hardlight_byte(sc: i32, dc: i32, sa: i32, da: i32) -> u32 {
364 let rc = if 2 * sc <= sa {
365 2 * sc * dc
366 } else {
367 sa * da - 2 * (da - dc) * (sa - sc)
368 };
369 clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa))
370}
371
372pub struct HardLight;
373
374impl Blend for HardLight {
375 fn blend(src: u32, dst: u32) -> u32 {
376 let sa = get_packed_a32(src) as i32;
377 let da = get_packed_a32(dst) as i32;
378 pack_argb32(
379 srcover_byte(sa as u32, da as u32),
380 hardlight_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
381 hardlight_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
382 hardlight_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
383 )
384 }
385}
386
387fn sqrt_bits(x: i32, count: i32) -> i32 {
389 debug_assert!(x >= 0 && count > 0 && count <= 30);
390
391 let mut root = 0;
392 let mut rem_hi = 0;
393 let mut rem_lo = x;
394
395 loop {
396 root <<= 1;
397
398 rem_hi = (rem_hi << 2) | (rem_lo >> 30);
399 rem_lo <<= 2;
400
401 let test_div = (root << 1) + 1;
402 if rem_hi >= test_div {
403 rem_hi -= test_div;
404 root += 1;
405 }
406 if -count < 0 {
407 break;
408 }
409 }
410
411 root
412}
413
414type U8Cpu = u32;
415
416fn sqrt_unit_byte(n: U8Cpu) -> U8Cpu {
418 sqrt_bits(n as i32, 15 + 4) as u32
419}
420
421fn softlight_byte(sc: i32, dc: i32, sa: i32, da: i32) -> u32 {
422 let m = if da != 0 { dc * 256 / da } else { 0 };
423 let rc = if 2 * sc <= sa {
424 dc * (sa + ((2 * sc - sa) * (256 - m) >> 8))
425 } else if 4 * dc <= da {
426 let tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m;
427 dc * sa + (da * (2 * sc - sa) * tmp >> 8)
428 } else {
429 let tmp = sqrt_unit_byte(m as u32) as i32 - m;
430 dc * sa + (da * (2 * sc - sa) * tmp >> 8)
431 };
432 clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa))
433}
434
435pub struct SoftLight;
436
437impl Blend for SoftLight {
438 fn blend(src: u32, dst: u32) -> u32 {
439 let sa = get_packed_a32(src) as i32;
440 let da = get_packed_a32(dst) as i32;
441 pack_argb32(
442 srcover_byte(sa as u32, da as u32),
443 softlight_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
444 softlight_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
445 softlight_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
446 )
447 }
448}
449
450
451fn clamp_signed_byte(n: i32) -> u32 {
452 if n < 0 {
453 0
454 } else if n > 255 {
455 255
456 } else {
457 n as u32
458 }
459}
460
461fn difference_byte(sc: i32, dc: i32, sa: i32, da: i32) -> u32 {
462 let tmp = (sc * da).min(dc * sa);
463 clamp_signed_byte(sc + dc - 2 * div255(tmp as u32) as i32)
464}
465
466pub struct Difference;
467
468impl Blend for Difference {
469 fn blend(src: u32, dst: u32) -> u32 {
470 let sa = get_packed_a32(src) as i32;
471 let da = get_packed_a32(dst) as i32;
472 pack_argb32(
473 srcover_byte(sa as u32, da as u32),
474 difference_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
475 difference_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
476 difference_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
477 )
478 }
479}
480
481fn exclusion_byte(sc: i32, dc: i32, _sa: i32, _da: i32) -> u32 {
482 let r = 255 * (sc + dc) - 2 * sc * dc;
487 clamp_div255round(r)
488}
489
490pub struct Exclusion;
491
492impl Blend for Exclusion {
493 fn blend(src: u32, dst: u32) -> u32 {
494 let sa = get_packed_a32(src) as i32;
495 let da = get_packed_a32(dst) as i32;
496 pack_argb32(
497 srcover_byte(sa as u32, da as u32),
498 exclusion_byte(get_packed_r32(src) as i32, get_packed_r32(dst) as i32, sa, da),
499 exclusion_byte(get_packed_g32(src) as i32, get_packed_g32(dst) as i32, sa, da),
500 exclusion_byte(get_packed_b32(src) as i32, get_packed_b32(dst) as i32, sa, da)
501 )
502 }
503}
504
505fn lum(r: i32, g: i32, b: i32) -> i32 {
511 div255((r * 77 + g * 150 + b * 28) as u32) as i32
512}
513
514fn mul_div(numer1: i32, numer2: i32, denom: i32) -> i32 {
515 ((numer1 as i64 * numer2 as i64) / denom as i64) as i32
516}
517
518fn minimum(a: i32, b: i32, c: i32) -> i32 {
519 a.min(b).min(c)
520}
521
522fn maximum(a: i32, b: i32, c: i32) -> i32 {
523 a.max(b).max(c)
524}
525
526fn clip_color(r: &mut i32, g: &mut i32, b: &mut i32, a: i32) {
527 let L = lum(*r, *g, *b);
528 let n = minimum(*r, *g, *b);
529 let x = maximum(*r, *g, *b);
530 let denom = L - n;
531 if (n < 0) && (denom != 0) { *r = L + mul_div(*r - L, L, denom);
533 *g = L + mul_div(*g - L, L, denom);
534 *b = L + mul_div(*b - L, L, denom);
535 }
536
537 let denom = x - L;
538 if (x > a) && (denom != 0) { let numer = a - L;
540 *r = L + mul_div(*r - L, numer, denom);
541 *g = L + mul_div(*g - L, numer, denom);
542 *b = L + mul_div(*b - L, numer, denom);
543 }
544}
545
546fn sat(r: i32, g: i32, b: i32) -> i32 {
547 maximum(r, g, b) - minimum(r, g, b)
548}
549
550fn set_saturation_components(cmin: &mut i32, cmind: &mut i32, cmax: &mut i32, s: i32) {
551 if *cmax > *cmin {
552 *cmind = mul_div(*cmind - *cmin, s, *cmax - *cmin);
553 *cmax = s;
554 } else {
555 *cmax = 0;
556 *cmind = 0;
557 }
558
559 *cmin = 0;
560}
561
562fn set_sat(r: &mut i32, g: &mut i32, b: &mut i32, s: i32) {
563 if *r <= *g {
564 if *g <= *b {
565 set_saturation_components(r, g, b, s);
566 } else if *r <= *b {
567 set_saturation_components(r, b, g, s);
568 } else {
569 set_saturation_components(b, r, g, s);
570 }
571 } else if *r <= *b {
572 set_saturation_components(g, r, b, s);
573 } else if *g <= *b {
574 set_saturation_components(g, b, r, s);
575 } else {
576 set_saturation_components(b, g, r, s);
577 }
578}
579
580fn set_lum(r: &mut i32, g: &mut i32, b: &mut i32, a: i32, l: i32) {
581 let d = l - lum(*r, *g, *b);
582 *r += d;
583 *g += d;
584 *b += d;
585
586 clip_color(r, g, b, a);
587}
588
589fn blendfunc_nonsep_byte(sc: i32, dc: i32, sa: i32, da: i32, blendval: i32) -> u32 {
591 clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval)
592}
593
594pub struct Hue;
595
596impl Blend for Hue {
597 fn blend(src: u32, dst: u32) -> u32 {
598 let sr = get_packed_r32(src) as i32;
599 let sg = get_packed_g32(src) as i32;
600 let sb = get_packed_b32(src) as i32;
601 let sa = get_packed_a32(src) as i32;
602
603 let dr = get_packed_r32(dst) as i32;
604 let dg = get_packed_g32(dst) as i32;
605 let db = get_packed_b32(dst) as i32;
606 let da = get_packed_a32(dst) as i32;
607 let mut Sr;
608 let mut Sg;
609 let mut Sb;
610
611 if sa != 0 && da != 0 {
612 Sr = sr * sa;
613 Sg = sg * sa;
614 Sb = sb * sa;
615 set_sat(&mut Sr, &mut Sg, &mut Sb, sat(dr, dg, db) * sa);
616 set_lum(&mut Sr, &mut Sg, &mut Sb, sa * da, lum(dr, dg, db) * sa);
617 } else {
618 Sr = 0;
619 Sg = 0;
620 Sb = 0;
621 }
622
623 pack_argb32(
624 srcover_byte(sa as u32, da as u32),
625 blendfunc_nonsep_byte(sr, dr, sa, da, Sr),
626 blendfunc_nonsep_byte(sg, dg, sa, da, Sg),
627 blendfunc_nonsep_byte(sb, db, sa, da, Sb)
628 )
629 }
630}
631
632pub struct Saturation;
633
634impl Blend for Saturation {
635 fn blend(src: u32, dst: u32) -> u32 {
636 let sr = get_packed_r32(src) as i32;
637 let sg = get_packed_g32(src) as i32;
638 let sb = get_packed_b32(src) as i32;
639 let sa = get_packed_a32(src) as i32;
640
641 let dr = get_packed_r32(dst) as i32;
642 let dg = get_packed_g32(dst) as i32;
643 let db = get_packed_b32(dst) as i32;
644 let da = get_packed_a32(dst) as i32;
645 let mut Dr;
646 let mut Dg;
647 let mut Db;
648
649 if sa != 0 && da != 0 {
650 Dr = dr * sa;
651 Dg = dg * sa;
652 Db = db * sa;
653 set_sat(&mut Dr, &mut Dg, &mut Db, sat(sr, sg, sb) * da);
654 set_lum(&mut Dr, &mut Dg, &mut Db, sa * da, lum(dr, dg, db) * sa);
655 } else {
656 Dr = 0;
657 Dg = 0;
658 Db = 0;
659 }
660
661 pack_argb32(
662 srcover_byte(sa as u32, da as u32),
663 blendfunc_nonsep_byte(sr, dr, sa, da, Dr),
664 blendfunc_nonsep_byte(sg, dg, sa, da, Dg),
665 blendfunc_nonsep_byte(sb, db, sa, da, Db)
666 )
667 }
668}
669
670pub struct Color;
671
672impl Blend for Color {
673 fn blend(src: u32, dst: u32) -> u32 {
674 let sr = get_packed_r32(src) as i32;
675 let sg = get_packed_g32(src) as i32;
676 let sb = get_packed_b32(src) as i32;
677 let sa = get_packed_a32(src) as i32;
678
679 let dr = get_packed_r32(dst) as i32;
680 let dg = get_packed_g32(dst) as i32;
681 let db = get_packed_b32(dst) as i32;
682 let da = get_packed_a32(dst) as i32;
683 let mut Sr;
684 let mut Sg;
685 let mut Sb;
686
687 if sa != 0 && da != 0 {
688 Sr = sr * sa;
689 Sg = sg * sa;
690 Sb = sb * sa;
691 set_lum(&mut Sr, &mut Sg, &mut Sb, sa * da, lum(dr, dg, db) * sa);
692 } else {
693 Sr = 0;
694 Sg = 0;
695 Sb = 0;
696 }
697
698 pack_argb32(
699 srcover_byte(sa as u32, da as u32),
700 blendfunc_nonsep_byte(sr, dr, sa, da, Sr),
701 blendfunc_nonsep_byte(sg, dg, sa, da, Sg),
702 blendfunc_nonsep_byte(sb, db, sa, da, Sb)
703 )
704 }
705}
706
707pub struct Luminosity;
708
709impl Blend for Luminosity {
710 fn blend(src: u32, dst: u32) -> u32 {
713 let sr = get_packed_r32(src) as i32;
714 let sg = get_packed_g32(src) as i32;
715 let sb = get_packed_b32(src) as i32;
716 let sa = get_packed_a32(src) as i32;
717
718 let dr = get_packed_r32(dst) as i32;
719 let dg = get_packed_g32(dst) as i32;
720 let db = get_packed_b32(dst) as i32;
721 let da = get_packed_a32(dst) as i32;
722 let mut Dr;
723 let mut Dg;
724 let mut Db;
725
726 if sa != 0 && da != 0 {
727 Dr = dr * sa;
728 Dg = dg * sa;
729 Db = db * sa;
730 set_lum(&mut Dr, &mut Dg, &mut Db, sa * da, lum(sr, sg, sb) * da);
731 } else {
732 Dr = 0;
733 Dg = 0;
734 Db = 0;
735 }
736
737 pack_argb32(
738 srcover_byte(sa as u32, da as u32),
739 blendfunc_nonsep_byte(sr, dr, sa, da, Dr),
740 blendfunc_nonsep_byte(sg, dg, sa, da, Dg),
741 blendfunc_nonsep_byte(sb, db, sa, da, Db)
742 )
743 }
744}