5#define FASTLED_INTERNAL
23#if !defined(FL_IS_AVR)
38 FL_ERROR(
"XY function not provided - using default [0][0]. Use blur2d with XYMap instead");
70 const fl::u16 numLeds =
static_cast<fl::u16
>(
leds.size());
74 for (fl::u16 i = 0; i < numLeds; ++i) {
111 leds[
xyMap.mapToIndex(i - 1, row)] += part;
126 leds[
xyMap.mapToIndex(col, i - 1)] += part;
138 if (
xyMap.isRectangularGrid()) {
149 rowBase[col - 1] += part;
165 leds[
xyMap.mapToIndex(i - 1, row)] += part;
177 if (
xyMap.isRectangularGrid()) {
187 pixels[(row - 1) *
width + col] += part;
203 leds[
xyMap.mapToIndex(col, i - 1)] += part;
211 const int w = canvas.
width;
212 const int h = canvas.
height;
216 for (
int row = 0; row < h; ++row) {
218 CRGB *rowBase = pixels + row * w;
219 for (
int col = 0; col < w; ++col) {
226 rowBase[col - 1] += part;
234 const int w = canvas.
width;
235 const int h = canvas.
height;
239 for (
int col = 0; col < w; ++col) {
241 for (
int row = 0; row < h; ++row) {
242 CRGB cur = pixels[row * w + col];
248 pixels[(row - 1) * w + col] += part;
249 pixels[row * w + col] =
cur;
293template <
typename RGB_T>
302 return CRGB(
static_cast<u8>(r),
static_cast<u8>(g),
307 if (a.
value == 255)
return make(r, g, b);
308 u16 a1 =
static_cast<u16
>(a.
value) + 1;
309 return CRGB(
static_cast<u8>((r * a1) >> 8),
310 static_cast<u8>((g * a1) >> 8),
311 static_cast<u8>((b * a1) >> 8));
315 if (a.
value >= 65535)
return make(r, g, b);
316 u32 a1 =
static_cast<u32
>(a.
value) + 1;
317 return CRGB(
static_cast<u8>((r * a1) >> 16),
318 static_cast<u8>((g * a1) >> 16),
319 static_cast<u8>((b * a1) >> 16));
335 if (a.
value == 255)
return make(r, g, b);
336 u32 a1 =
static_cast<u32
>(a.
value) + 1;
337 return make((r * a1) >> 8, (g * a1) >> 8, (b * a1) >> 8);
341 if (a.
value >= 65535)
return make(r, g, b);
342 u32 a1 =
static_cast<u32
>(a.
value) + 1;
343 return make((r * a1) >> 16, (g * a1) >> 16, (b * a1) >> 16);
348template <
typename RGB_T>
351 if (
static_cast<int>(buf.
size()) < minSize) {
360template <
int R,
typename RGB_T,
typename acc_t>
363template <
typename RGB_T,
typename acc_t>
366 acc_t &r, acc_t &g, acc_t &b) {
368 r = P::ch(row[
x].r); g = P::ch(row[
x].g); b = P::ch(row[
x].b);
372template <
typename RGB_T,
typename acc_t>
375 acc_t &r, acc_t &g, acc_t &b) {
379 {
const RGB_T &px = row[
x-1]; r += p.ch(px.r); g += p.ch(px.g); b += p.ch(px.b); }
380 {
const RGB_T &px = row[
x]; r += p.ch(px.r) * 2; g += p.ch(px.g) * 2; b += p.ch(px.b) * 2; }
381 {
const RGB_T &px = row[
x+1]; r += p.ch(px.r); g += p.ch(px.g); b += p.ch(px.b); }
385template <
typename RGB_T,
typename acc_t>
388 acc_t &r, acc_t &g, acc_t &b) {
392 const RGB_T &pm2 = row[
x-2], &pm1 = row[
x-1], &pc = row[
x], &pp1 = row[
x+1], &pp2 = row[
x+2];
393 const acc_t s04r = p.ch(pm2.r) + p.ch(pp2.r), s13r = p.ch(pm1.r) + p.ch(pp1.r);
394 const acc_t s04g = p.ch(pm2.g) + p.ch(pp2.g), s13g = p.ch(pm1.g) + p.ch(pp1.g);
395 const acc_t s04b = p.ch(pm2.b) + p.ch(pp2.b), s13b = p.ch(pm1.b) + p.ch(pp1.b);
396 r = s04r + s13r * 4 + p.ch(pc.r) * 6;
397 g = s04g + s13g * 4 + p.ch(pc.g) * 6;
398 b = s04b + s13b * 4 + p.ch(pc.b) * 6;
402template <
typename RGB_T,
typename acc_t>
405 acc_t &r, acc_t &g, acc_t &b) {
409 const RGB_T &pm3 = row[
x-3], &pm2 = row[
x-2], &pm1 = row[
x-1], &pc = row[
x];
410 const RGB_T &pp1 = row[
x+1], &pp2 = row[
x+2], &pp3 = row[
x+3];
411 const acc_t s06r = p.ch(pm3.r) + p.ch(pp3.r), s15r = p.ch(pm2.r) + p.ch(pp2.r), s24r = p.ch(pm1.r) + p.ch(pp1.r);
412 const acc_t s06g = p.ch(pm3.g) + p.ch(pp3.g), s15g = p.ch(pm2.g) + p.ch(pp2.g), s24g = p.ch(pm1.g) + p.ch(pp1.g);
413 const acc_t s06b = p.ch(pm3.b) + p.ch(pp3.b), s15b = p.ch(pm2.b) + p.ch(pp2.b), s24b = p.ch(pm1.b) + p.ch(pp1.b);
414 r = s06r + s15r * 6 + s24r * 15 + p.ch(pc.r) * 20;
415 g = s06g + s15g * 6 + s24g * 15 + p.ch(pc.g) * 20;
416 b = s06b + s15b * 6 + s24b * 15 + p.ch(pc.b) * 20;
420template <
typename RGB_T,
typename acc_t>
423 acc_t &r, acc_t &g, acc_t &b) {
427 const RGB_T &pm4 = row[
x-4], &pm3 = row[
x-3], &pm2 = row[
x-2], &pm1 = row[
x-1], &pc = row[
x];
428 const RGB_T &pp1 = row[
x+1], &pp2 = row[
x+2], &pp3 = row[
x+3], &pp4 = row[
x+4];
429 const acc_t s08r = p.ch(pm4.r) + p.ch(pp4.r), s17r = p.ch(pm3.r) + p.ch(pp3.r);
430 const acc_t s26r = p.ch(pm2.r) + p.ch(pp2.r), s35r = p.ch(pm1.r) + p.ch(pp1.r);
431 const acc_t s08g = p.ch(pm4.g) + p.ch(pp4.g), s17g = p.ch(pm3.g) + p.ch(pp3.g);
432 const acc_t s26g = p.ch(pm2.g) + p.ch(pp2.g), s35g = p.ch(pm1.g) + p.ch(pp1.g);
433 const acc_t s08b = p.ch(pm4.b) + p.ch(pp4.b), s17b = p.ch(pm3.b) + p.ch(pp3.b);
434 const acc_t s26b = p.ch(pm2.b) + p.ch(pp2.b), s35b = p.ch(pm1.b) + p.ch(pp1.b);
435 r = s08r + s17r * 8 + s26r * 28 + s35r * 56 + p.ch(pc.r) * 70;
436 g = s08g + s17g * 8 + s26g * 28 + s35g * 56 + p.ch(pc.g) * 70;
437 b = s08b + s17b * 8 + s26b * 28 + s35b * 56 + p.ch(pc.b) * 70;
450#if defined(FL_IS_AVR)
452template <
int R>
struct conv1ch;
457template <>
struct conv1ch<0> {
458 static inline u16 __attribute__((always_inline)) apply(
const u8 *c) {
463template <>
struct conv1ch<1> {
464 static inline u16 __attribute__((always_inline)) apply(
const u8 *c) {
465 constexpr int S =
sizeof(
CRGB);
468 return (u16)p[0] * 64 + (u16)p[S] * 128 + (u16)p[2*S] * 64;
472template <>
struct conv1ch<2> {
473 static inline u16 __attribute__((always_inline)) apply(
const u8 *c) {
474 constexpr int S =
sizeof(
CRGB);
475 const u8 *p = c - 2*S;
477 return (u16)p[0] * 16 + (u16)p[S] * 64 + (u16)p[2*S] * 96
478 + (u16)p[3*S] * 64 + (u16)p[4*S] * 16;
482template <>
struct conv1ch<3> {
483 static inline u16 __attribute__((always_inline)) apply(
const u8 *c) {
484 constexpr int S =
sizeof(
CRGB);
485 const u8 *p = c - 3*S;
487 return (u16)p[0] * 4 + (u16)p[S] * 24 + (u16)p[2*S] * 60
488 + (u16)p[3*S] * 80 + (u16)p[4*S] * 60 + (u16)p[5*S] * 24
493template <>
struct conv1ch<4> {
494 static inline u16 __attribute__((always_inline)) apply(
const u8 *c) {
495 constexpr int S =
sizeof(
CRGB);
496 const u8 *p = c - 4*S;
498 return (u16)p[0] + (u16)p[S] * 8 + (u16)p[2*S] * 28
499 + (u16)p[3*S] * 56 + (u16)p[4*S] * 70 + (u16)p[5*S] * 56
500 + (u16)p[6*S] * 28 + (u16)p[7*S] * 8 + (u16)p[8*S];
507static void apply_pass_1ch(
const CRGB *pad,
CRGB *out,
int count,
int stride) {
508 constexpr int shift = (R == 0) ? 0 : 8;
509 for (
int i = 0; i < count; ++i) {
510 const u8 *base = pad[R + i].raw;
511 out->r =
static_cast<u8>(conv1ch<R>::apply(base + 0) >> shift);
512 out->g =
static_cast<u8>(conv1ch<R>::apply(base + 1) >> shift);
513 out->b =
static_cast<u8>(conv1ch<R>::apply(base + 2) >> shift);
521static void apply_pass_alpha_1ch(
const CRGB *pad,
CRGB *out,
int count,
522 int stride, alpha8 alpha) {
523 constexpr int shift = (R == 0) ? 0 : 8;
524 u16 a1 =
static_cast<u16
>(alpha.value) + 1;
525 for (
int i = 0; i < count; ++i) {
526 const u8 *base = pad[R + i].raw;
527 u16 r = conv1ch<R>::apply(base + 0) >> shift;
528 u16 g = conv1ch<R>::apply(base + 1) >> shift;
529 u16 b = conv1ch<R>::apply(base + 2) >> shift;
530 out->r =
static_cast<u8>((r * a1) >> 8);
531 out->g =
static_cast<u8>((g * a1) >> 8);
532 out->b =
static_cast<u8>((b * a1) >> 8);
540static void apply_pass_alpha_1ch(
const CRGB *pad,
CRGB *out,
int count,
541 int stride, alpha16 alpha) {
542 constexpr int shift = (R == 0) ? 0 : 8;
543 u32 a1 =
static_cast<u32
>(alpha.value) + 1;
544 for (
int i = 0; i < count; ++i) {
545 const u8 *base = pad[R + i].raw;
546 u16 r = conv1ch<R>::apply(base + 0) >> shift;
547 u16 g = conv1ch<R>::apply(base + 1) >> shift;
548 u16 b = conv1ch<R>::apply(base + 2) >> shift;
549 out->r =
static_cast<u8>((r * a1) >> 16);
550 out->g =
static_cast<u8>((g * a1) >> 16);
551 out->b =
static_cast<u8>((b * a1) >> 16);
561template <
int R,
typename RGB_T,
typename acc_t>
563static void apply_pass(
const RGB_T *pad, RGB_T *out,
int count,
int stride) {
564 constexpr int shift = 2 * R;
566 for (
int i = 0; i < count; ++i) {
569 *out = P::make(
static_cast<acc_t
>(r >> shift),
570 static_cast<acc_t
>(g >> shift),
571 static_cast<acc_t
>(b >> shift));
576template <
int R,
typename RGB_T,
typename acc_t,
typename AlphaT>
579 int stride, AlphaT alpha) {
580 constexpr int shift = 2 * R;
582 for (
int i = 0; i < count; ++i) {
585 *out = P::make(
static_cast<acc_t
>(r >> shift),
586 static_cast<acc_t
>(g >> shift),
587 static_cast<acc_t
>(b >> shift), alpha);
599#if !defined(FL_IS_AVR)
611 for (; i + 63 < nbytes; i += 64) {
612 auto va0 = fsimd::load_u8_32(a+i), vb0 = fsimd::load_u8_32(b+i), vc0 = fsimd::load_u8_32(c+i);
613 auto va1 = fsimd::load_u8_32(a+i+32), vb1 = fsimd::load_u8_32(b+i+32), vc1 = fsimd::load_u8_32(c+i+32);
614 fsimd::store_u8_32(out+i, fsimd::avg_round_u8_32(fsimd::avg_round_u8_32(va0, vc0), vb0));
615 fsimd::store_u8_32(out+i+32, fsimd::avg_round_u8_32(fsimd::avg_round_u8_32(va1, vc1), vb1));
617 for (; i + 31 < nbytes; i += 32) {
618 auto va = fsimd::load_u8_32(a+i), vb = fsimd::load_u8_32(b+i), vc = fsimd::load_u8_32(c+i);
619 fsimd::store_u8_32(out+i, fsimd::avg_round_u8_32(fsimd::avg_round_u8_32(va, vc), vb));
621 for (; i + 15 < nbytes; i += 16) {
622 auto va = fsimd::load_u8_16(a+i), vb = fsimd::load_u8_16(b+i), vc = fsimd::load_u8_16(c+i);
623 fsimd::store_u8_16(out+i, fsimd::avg_round_u8_16(fsimd::avg_round_u8_16(va, vc), vb));
625 for (; i < nbytes; ++i)
626 out[i] = (
u8)(((u16)a[i] + ((u16)b[i] << 1) + (u16)c[i]) >> 2);
634 const u8 *p3,
const u8 *p4,
635 u8 *out,
int nbytes) {
637 const auto w4w = fsimd::set1_u16_16(4), w6w = fsimd::set1_u16_16(6);
638 const auto w4 = fsimd::set1_u16_8(4), w6 = fsimd::set1_u16_8(6);
640 for (; i + 31 < nbytes; i += 32) {
641 auto v0 = fsimd::load_u8_32(p0+i), v1 = fsimd::load_u8_32(p1+i);
642 auto v2 = fsimd::load_u8_32(p2+i), v3 = fsimd::load_u8_32(p3+i), v4 = fsimd::load_u8_32(p4+i);
643 auto s04 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v0), fsimd::widen_lo_u8x32_to_u16(v4));
644 auto s13 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v1), fsimd::widen_lo_u8x32_to_u16(v3));
645 auto lo = fsimd::add_u16_16(s04, fsimd::add_u16_16(fsimd::mullo_u16_16(s13, w4w), fsimd::mullo_u16_16(fsimd::widen_lo_u8x32_to_u16(v2), w6w)));
646 lo = fsimd::srli_u16_16(lo, 4);
647 auto s04h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v0), fsimd::widen_hi_u8x32_to_u16(v4));
648 auto s13h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v1), fsimd::widen_hi_u8x32_to_u16(v3));
649 auto hi = fsimd::add_u16_16(s04h, fsimd::add_u16_16(fsimd::mullo_u16_16(s13h, w4w), fsimd::mullo_u16_16(fsimd::widen_hi_u8x32_to_u16(v2), w6w)));
650 hi = fsimd::srli_u16_16(hi, 4);
651 fsimd::store_u8_32(out+i, fsimd::narrow_u16x16_to_u8(lo, hi));
653 for (; i + 15 < nbytes; i += 16) {
654 auto v0 = fsimd::load_u8_16(p0+i), v1 = fsimd::load_u8_16(p1+i);
655 auto v2 = fsimd::load_u8_16(p2+i), v3 = fsimd::load_u8_16(p3+i), v4 = fsimd::load_u8_16(p4+i);
656 auto s04 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v0), fsimd::widen_lo_u8_to_u16(v4));
657 auto s13 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v1), fsimd::widen_lo_u8_to_u16(v3));
658 auto lo = fsimd::add_u16_8(s04, fsimd::add_u16_8(fsimd::mullo_u16_8(s13, w4), fsimd::mullo_u16_8(fsimd::widen_lo_u8_to_u16(v2), w6)));
659 lo = fsimd::srli_u16_8(lo, 4);
660 auto s04h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v0), fsimd::widen_hi_u8_to_u16(v4));
661 auto s13h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v1), fsimd::widen_hi_u8_to_u16(v3));
662 auto hi = fsimd::add_u16_8(s04h, fsimd::add_u16_8(fsimd::mullo_u16_8(s13h, w4), fsimd::mullo_u16_8(fsimd::widen_hi_u8_to_u16(v2), w6)));
663 hi = fsimd::srli_u16_8(hi, 4);
664 fsimd::store_u8_16(out+i, fsimd::narrow_u16_to_u8(lo, hi));
666 for (; i < nbytes; ++i) {
667 u16 s04 = (u16)p0[i] + (u16)p4[i];
668 u16 s13 = (u16)p1[i] + (u16)p3[i];
669 out[i] = (
u8)((s04 + s13 * 4 + (u16)p2[i] * 6) >> 4);
675 const u8 *p3,
const u8 *p4,
const u8 *p5,
676 const u8 *p6,
u8 *out,
int nbytes) {
678 const auto w6w = fsimd::set1_u16_16(6), w15w = fsimd::set1_u16_16(15), w20w = fsimd::set1_u16_16(20);
679 const auto w6 = fsimd::set1_u16_8(6), w15 = fsimd::set1_u16_8(15), w20 = fsimd::set1_u16_8(20);
681 for (; i + 31 < nbytes; i += 32) {
682 auto v0 = fsimd::load_u8_32(p0+i), v1 = fsimd::load_u8_32(p1+i), v2 = fsimd::load_u8_32(p2+i);
683 auto v3 = fsimd::load_u8_32(p3+i), v4 = fsimd::load_u8_32(p4+i), v5 = fsimd::load_u8_32(p5+i);
684 auto v6v = fsimd::load_u8_32(p6+i);
685 auto s06 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v0), fsimd::widen_lo_u8x32_to_u16(v6v));
686 auto s15 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v1), fsimd::widen_lo_u8x32_to_u16(v5));
687 auto s24 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v2), fsimd::widen_lo_u8x32_to_u16(v4));
688 auto lo = fsimd::add_u16_16(s06, fsimd::add_u16_16(fsimd::mullo_u16_16(s15, w6w),
689 fsimd::add_u16_16(fsimd::mullo_u16_16(s24, w15w), fsimd::mullo_u16_16(fsimd::widen_lo_u8x32_to_u16(v3), w20w))));
690 lo = fsimd::srli_u16_16(lo, 6);
691 auto s06h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v0), fsimd::widen_hi_u8x32_to_u16(v6v));
692 auto s15h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v1), fsimd::widen_hi_u8x32_to_u16(v5));
693 auto s24h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v2), fsimd::widen_hi_u8x32_to_u16(v4));
694 auto hi = fsimd::add_u16_16(s06h, fsimd::add_u16_16(fsimd::mullo_u16_16(s15h, w6w),
695 fsimd::add_u16_16(fsimd::mullo_u16_16(s24h, w15w), fsimd::mullo_u16_16(fsimd::widen_hi_u8x32_to_u16(v3), w20w))));
696 hi = fsimd::srli_u16_16(hi, 6);
697 fsimd::store_u8_32(out+i, fsimd::narrow_u16x16_to_u8(lo, hi));
699 for (; i + 15 < nbytes; i += 16) {
700 auto v0 = fsimd::load_u8_16(p0+i), v1 = fsimd::load_u8_16(p1+i), v2 = fsimd::load_u8_16(p2+i);
701 auto v3 = fsimd::load_u8_16(p3+i), v4 = fsimd::load_u8_16(p4+i), v5 = fsimd::load_u8_16(p5+i);
702 auto v6v = fsimd::load_u8_16(p6+i);
703 auto s06 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v0), fsimd::widen_lo_u8_to_u16(v6v));
704 auto s15 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v1), fsimd::widen_lo_u8_to_u16(v5));
705 auto s24 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v2), fsimd::widen_lo_u8_to_u16(v4));
706 auto lo = fsimd::add_u16_8(s06, fsimd::add_u16_8(fsimd::mullo_u16_8(s15, w6),
707 fsimd::add_u16_8(fsimd::mullo_u16_8(s24, w15), fsimd::mullo_u16_8(fsimd::widen_lo_u8_to_u16(v3), w20))));
708 lo = fsimd::srli_u16_8(lo, 6);
709 auto s06h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v0), fsimd::widen_hi_u8_to_u16(v6v));
710 auto s15h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v1), fsimd::widen_hi_u8_to_u16(v5));
711 auto s24h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v2), fsimd::widen_hi_u8_to_u16(v4));
712 auto hi = fsimd::add_u16_8(s06h, fsimd::add_u16_8(fsimd::mullo_u16_8(s15h, w6),
713 fsimd::add_u16_8(fsimd::mullo_u16_8(s24h, w15), fsimd::mullo_u16_8(fsimd::widen_hi_u8_to_u16(v3), w20))));
714 hi = fsimd::srli_u16_8(hi, 6);
715 fsimd::store_u8_16(out+i, fsimd::narrow_u16_to_u8(lo, hi));
717 for (; i < nbytes; ++i) {
718 u16 s06=(u16)p0[i]+(u16)p6[i], s15=(u16)p1[i]+(u16)p5[i], s24=(u16)p2[i]+(u16)p4[i];
719 out[i]=(
u8)((s06+s15*6+s24*15+(u16)p3[i]*20)>>6);
725 const u8 *p4,
const u8 *p5,
const u8 *p6,
const u8 *p7,
726 const u8 *p8,
u8 *out,
int nbytes) {
728 const auto w8w = fsimd::set1_u16_16(8), w28w = fsimd::set1_u16_16(28);
729 const auto w56w = fsimd::set1_u16_16(56), w70w = fsimd::set1_u16_16(70);
730 const auto w8 = fsimd::set1_u16_8(8), w28 = fsimd::set1_u16_8(28);
731 const auto w56 = fsimd::set1_u16_8(56), w70 = fsimd::set1_u16_8(70);
733 for (; i + 31 < nbytes; i += 32) {
734 auto v0 = fsimd::load_u8_32(p0+i), v1 = fsimd::load_u8_32(p1+i), v2 = fsimd::load_u8_32(p2+i);
735 auto v3 = fsimd::load_u8_32(p3+i), v4 = fsimd::load_u8_32(p4+i), v5 = fsimd::load_u8_32(p5+i);
736 auto v6v = fsimd::load_u8_32(p6+i), v7 = fsimd::load_u8_32(p7+i), v8v = fsimd::load_u8_32(p8+i);
737 auto s08 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v0), fsimd::widen_lo_u8x32_to_u16(v8v));
738 auto s17 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v1), fsimd::widen_lo_u8x32_to_u16(v7));
739 auto s26 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v2), fsimd::widen_lo_u8x32_to_u16(v6v));
740 auto s35 = fsimd::add_u16_16(fsimd::widen_lo_u8x32_to_u16(v3), fsimd::widen_lo_u8x32_to_u16(v5));
741 auto lo = fsimd::add_u16_16(s08, fsimd::add_u16_16(fsimd::mullo_u16_16(s17, w8w),
742 fsimd::add_u16_16(fsimd::mullo_u16_16(s26, w28w),
743 fsimd::add_u16_16(fsimd::mullo_u16_16(s35, w56w), fsimd::mullo_u16_16(fsimd::widen_lo_u8x32_to_u16(v4), w70w)))));
744 lo = fsimd::srli_u16_16(lo, 8);
745 auto s08h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v0), fsimd::widen_hi_u8x32_to_u16(v8v));
746 auto s17h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v1), fsimd::widen_hi_u8x32_to_u16(v7));
747 auto s26h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v2), fsimd::widen_hi_u8x32_to_u16(v6v));
748 auto s35h = fsimd::add_u16_16(fsimd::widen_hi_u8x32_to_u16(v3), fsimd::widen_hi_u8x32_to_u16(v5));
749 auto hi = fsimd::add_u16_16(s08h, fsimd::add_u16_16(fsimd::mullo_u16_16(s17h, w8w),
750 fsimd::add_u16_16(fsimd::mullo_u16_16(s26h, w28w),
751 fsimd::add_u16_16(fsimd::mullo_u16_16(s35h, w56w), fsimd::mullo_u16_16(fsimd::widen_hi_u8x32_to_u16(v4), w70w)))));
752 hi = fsimd::srli_u16_16(hi, 8);
753 fsimd::store_u8_32(out+i, fsimd::narrow_u16x16_to_u8(lo, hi));
755 for (; i + 15 < nbytes; i += 16) {
756 auto v0 = fsimd::load_u8_16(p0+i), v1 = fsimd::load_u8_16(p1+i), v2 = fsimd::load_u8_16(p2+i);
757 auto v3 = fsimd::load_u8_16(p3+i), v4 = fsimd::load_u8_16(p4+i), v5 = fsimd::load_u8_16(p5+i);
758 auto v6v = fsimd::load_u8_16(p6+i), v7 = fsimd::load_u8_16(p7+i), v8v = fsimd::load_u8_16(p8+i);
759 auto s08 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v0), fsimd::widen_lo_u8_to_u16(v8v));
760 auto s17 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v1), fsimd::widen_lo_u8_to_u16(v7));
761 auto s26 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v2), fsimd::widen_lo_u8_to_u16(v6v));
762 auto s35 = fsimd::add_u16_8(fsimd::widen_lo_u8_to_u16(v3), fsimd::widen_lo_u8_to_u16(v5));
763 auto lo = fsimd::add_u16_8(s08, fsimd::add_u16_8(fsimd::mullo_u16_8(s17, w8),
764 fsimd::add_u16_8(fsimd::mullo_u16_8(s26, w28),
765 fsimd::add_u16_8(fsimd::mullo_u16_8(s35, w56), fsimd::mullo_u16_8(fsimd::widen_lo_u8_to_u16(v4), w70)))));
766 lo = fsimd::srli_u16_8(lo, 8);
767 auto s08h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v0), fsimd::widen_hi_u8_to_u16(v8v));
768 auto s17h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v1), fsimd::widen_hi_u8_to_u16(v7));
769 auto s26h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v2), fsimd::widen_hi_u8_to_u16(v6v));
770 auto s35h = fsimd::add_u16_8(fsimd::widen_hi_u8_to_u16(v3), fsimd::widen_hi_u8_to_u16(v5));
771 auto hi = fsimd::add_u16_8(s08h, fsimd::add_u16_8(fsimd::mullo_u16_8(s17h, w8),
772 fsimd::add_u16_8(fsimd::mullo_u16_8(s26h, w28),
773 fsimd::add_u16_8(fsimd::mullo_u16_8(s35h, w56), fsimd::mullo_u16_8(fsimd::widen_hi_u8_to_u16(v4), w70)))));
774 hi = fsimd::srli_u16_8(hi, 8);
775 fsimd::store_u8_16(out+i, fsimd::narrow_u16_to_u8(lo, hi));
777 for (; i < nbytes; ++i) {
778 u16 s08=(u16)p0[i]+(u16)p8[i], s17=(u16)p1[i]+(u16)p7[i];
779 u16 s26=(u16)p2[i]+(u16)p6[i], s35=(u16)p3[i]+(u16)p5[i];
780 out[i]=(
u8)((s08+s17*8+s26*28+s35*56+(u16)p4[i]*70)>>8);
789 template <
typename RGB_T>
790 static void apply(RGB_T **bufs,
const RGB_T **,
u8 *out,
int nbytes) {
796 template <
typename RGB_T>
797 static void apply(RGB_T **bufs,
const RGB_T **fwd,
u8 *out,
int nbytes) {
799 (
const u8*)fwd[0], out, nbytes);
804 template <
typename RGB_T>
805 static void apply(RGB_T **bufs,
const RGB_T **fwd,
u8 *out,
int nbytes) {
807 (
const u8*)bufs[2], (
const u8*)fwd[0],
808 (
const u8*)fwd[1], out, nbytes);
813 template <
typename RGB_T>
814 static void apply(RGB_T **bufs,
const RGB_T **fwd,
u8 *out,
int nbytes) {
816 (
const u8*)bufs[2], (
const u8*)bufs[3],
817 (
const u8*)fwd[0], (
const u8*)fwd[1],
818 (
const u8*)fwd[2], out, nbytes);
823 template <
typename RGB_T>
824 static void apply(RGB_T **bufs,
const RGB_T **fwd,
u8 *out,
int nbytes) {
826 (
const u8*)bufs[2], (
const u8*)bufs[3],
827 (
const u8*)bufs[4], (
const u8*)fwd[0],
828 (
const u8*)fwd[1], (
const u8*)fwd[2],
829 (
const u8*)fwd[3], out, nbytes);
837 static void apply(
const u8 *pb,
int,
u8 *ob,
int nbytes,
u8 *,
int) {
843 static void apply(
const u8 *pb,
int S,
u8 *ob,
int nbytes,
u8 *,
int) {
849 static void apply(
const u8 *pb,
int S,
u8 *ob,
int nbytes,
u8 *,
int) {
858 static void apply(
const u8 *pb,
int S,
u8 *ob,
int nbytes,
u8 *,
int) {
859 simd_conv_r3(pb, pb+S, pb+2*S, pb+3*S, pb+4*S, pb+5*S, pb+6*S, ob, nbytes);
864 static void apply(
const u8 *pb,
int S,
u8 *ob,
int nbytes,
u8 *,
int) {
865 simd_conv_r4(pb, pb+S, pb+2*S, pb+3*S, pb+4*S, pb+5*S, pb+6*S, pb+7*S, pb+8*S, ob, nbytes);
873template <
typename RGB_T,
typename acc_t>
876 acc_t &r, acc_t &g, acc_t &b) {
878 r = p.ch(bufs[0][
x].r);
879 g = p.ch(bufs[0][
x].g);
880 b = p.ch(bufs[0][
x].b);
884template <
typename RGB_T,
typename acc_t>
887 acc_t &r, acc_t &g, acc_t &b) {
889 r = (p.ch(bufs[0][
x].r) + p.ch(fwd[0][
x].r)) + (p.ch(bufs[1][
x].r) << 1);
890 g = (p.ch(bufs[0][
x].g) + p.ch(fwd[0][
x].g)) + (p.ch(bufs[1][
x].g) << 1);
891 b = (p.ch(bufs[0][
x].b) + p.ch(fwd[0][
x].b)) + (p.ch(bufs[1][
x].b) << 1);
895template <
typename RGB_T,
typename acc_t>
898 acc_t &r, acc_t &g, acc_t &b) {
900 const acc_t sr04 = p.ch(bufs[0][
x].r) + p.ch(fwd[1][
x].r);
901 const acc_t sg04 = p.ch(bufs[0][
x].g) + p.ch(fwd[1][
x].g);
902 const acc_t sb04 = p.ch(bufs[0][
x].b) + p.ch(fwd[1][
x].b);
903 const acc_t sr13 = p.ch(bufs[1][
x].r) + p.ch(fwd[0][
x].r);
904 const acc_t sg13 = p.ch(bufs[1][
x].g) + p.ch(fwd[0][
x].g);
905 const acc_t sb13 = p.ch(bufs[1][
x].b) + p.ch(fwd[0][
x].b);
906 r = sr04 + sr13 * 4 + p.ch(bufs[2][
x].r) * 6;
907 g = sg04 + sg13 * 4 + p.ch(bufs[2][
x].g) * 6;
908 b = sb04 + sb13 * 4 + p.ch(bufs[2][
x].b) * 6;
912template <
typename RGB_T,
typename acc_t>
915 acc_t &r, acc_t &g, acc_t &b) {
917 const acc_t sr06 = p.ch(bufs[0][
x].r) + p.ch(fwd[2][
x].r);
918 const acc_t sg06 = p.ch(bufs[0][
x].g) + p.ch(fwd[2][
x].g);
919 const acc_t sb06 = p.ch(bufs[0][
x].b) + p.ch(fwd[2][
x].b);
920 const acc_t sr15 = p.ch(bufs[1][
x].r) + p.ch(fwd[1][
x].r);
921 const acc_t sg15 = p.ch(bufs[1][
x].g) + p.ch(fwd[1][
x].g);
922 const acc_t sb15 = p.ch(bufs[1][
x].b) + p.ch(fwd[1][
x].b);
923 const acc_t sr24 = p.ch(bufs[2][
x].r) + p.ch(fwd[0][
x].r);
924 const acc_t sg24 = p.ch(bufs[2][
x].g) + p.ch(fwd[0][
x].g);
925 const acc_t sb24 = p.ch(bufs[2][
x].b) + p.ch(fwd[0][
x].b);
926 r = sr06 + sr15 * 6 + sr24 * 15 + p.ch(bufs[3][
x].r) * 20;
927 g = sg06 + sg15 * 6 + sg24 * 15 + p.ch(bufs[3][
x].g) * 20;
928 b = sb06 + sb15 * 6 + sb24 * 15 + p.ch(bufs[3][
x].b) * 20;
932template <
typename RGB_T,
typename acc_t>
935 acc_t &r, acc_t &g, acc_t &b) {
937 const acc_t sr08 = p.ch(bufs[0][
x].r) + p.ch(fwd[3][
x].r);
938 const acc_t sg08 = p.ch(bufs[0][
x].g) + p.ch(fwd[3][
x].g);
939 const acc_t sb08 = p.ch(bufs[0][
x].b) + p.ch(fwd[3][
x].b);
940 const acc_t sr17 = p.ch(bufs[1][
x].r) + p.ch(fwd[2][
x].r);
941 const acc_t sg17 = p.ch(bufs[1][
x].g) + p.ch(fwd[2][
x].g);
942 const acc_t sb17 = p.ch(bufs[1][
x].b) + p.ch(fwd[2][
x].b);
943 const acc_t sr26 = p.ch(bufs[2][
x].r) + p.ch(fwd[1][
x].r);
944 const acc_t sg26 = p.ch(bufs[2][
x].g) + p.ch(fwd[1][
x].g);
945 const acc_t sb26 = p.ch(bufs[2][
x].b) + p.ch(fwd[1][
x].b);
946 const acc_t sr35 = p.ch(bufs[3][
x].r) + p.ch(fwd[0][
x].r);
947 const acc_t sg35 = p.ch(bufs[3][
x].g) + p.ch(fwd[0][
x].g);
948 const acc_t sb35 = p.ch(bufs[3][
x].b) + p.ch(fwd[0][
x].b);
949 r = sr08 + sr17 * 8 + sr26 * 28 + sr35 * 56 + p.ch(bufs[4][
x].r) * 70;
950 g = sg08 + sg17 * 8 + sg26 * 28 + sg35 * 56 + p.ch(bufs[4][
x].g) * 70;
951 b = sb08 + sb17 * 8 + sb26 * 28 + sb35 * 56 + p.ch(bufs[4][
x].b) * 70;
963#if !defined(FL_IS_AVR)
965template <
int R,
typename RGB_T,
typename acc_t,
bool ApplyAlpha,
typename AlphaT>
968 RGB_T *pixels,
int w,
int h,
969 RGB_T *scratch, AlphaT alpha)
971 constexpr int shift = 2 * R;
976 RGB_T *bufs[5] = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr};
977 for (
int i = 0; i <= R; ++i)
978 bufs[i] = scratch + i * w;
979 RGB_T *zero_row = scratch + (R + 1) * w;
984 for (
int y = 0;
y < h; ++
y) {
985 RGB_T *out_row = pixels +
y * w;
991 const RGB_T *fwd[4] = {zero_row, zero_row, zero_row, zero_row};
992 for (
int k = 0; k < R; ++k)
993 fwd[k] = (
y + 1 + k < h) ? (pixels + (
y + 1 + k) * w) : zero_row;
999 const int prefetch_y =
y + R + 2;
1000 if (prefetch_y < h) {
1001 const char *pf = (
const char *)(pixels + prefetch_y * w);
1002 const int row_bytes = w * (int)
sizeof(RGB_T);
1003 for (
int off = 0; off < row_bytes; off += 64)
1004 __builtin_prefetch(pf + off, 0, 3);
1013 if (
sizeof(
typename RGB_T::fp) == 1 && !ApplyAlpha) {
1015 const int nbytes = w * (int)
sizeof(RGB_T);
1016 u8 *ob = (
u8 *)out_row;
1021 for (
int x = 0;
x < w; ++
x) {
1027 out_row[
x] = P::make(
static_cast<acc_t
>(r >> shift),
1028 static_cast<acc_t
>(g >> shift),
1029 static_cast<acc_t
>(b >> shift), alpha);
1031 out_row[
x] = P::make(
static_cast<acc_t
>(r >> shift),
1032 static_cast<acc_t
>(g >> shift),
1033 static_cast<acc_t
>(b >> shift));
1039 RGB_T *recycled = bufs[0];
1040 for (
int i = 0; i < R; ++i) bufs[i] = bufs[i + 1];
1048template <
int hR,
int vR,
typename RGB_T>
1050 int hPad = 2 * hR + w;
1051#if defined(FL_IS_AVR)
1052 int vPad = 2 * vR + h;
1054 int vPad = vR > 0 ? (vR + 2) * w : 0;
1056 return hPad > vPad ? hPad : vPad;
1061template <
int R,
typename RGB_T,
typename acc_t,
bool ApplyAlpha,
typename AlphaT>
1063void hpass_row(RGB_T *pad, RGB_T *out,
int w, AlphaT alpha) {
1064#if defined(FL_IS_AVR)
1066 apply_pass_alpha_1ch<R>(pad, out, w, 1, alpha);
1068 apply_pass_1ch<R>(pad, out, w, 1);
1071 if (
sizeof(
typename RGB_T::fp) == 1 && !ApplyAlpha) {
1072 constexpr int S = (int)
sizeof(RGB_T);
1073 const int nbytes = w * S;
1074 const u8 *pb = (
const u8 *)pad;
1077 pb, S, ob, nbytes, (
u8 *)(pad + 2 * R + w), w);
1078 }
else if (ApplyAlpha) {
1087template <
int R,
typename RGB_T,
typename acc_t,
bool ApplyAlpha,
typename AlphaT>
1088static void vpass_full(RGB_T *pixels,
int w,
int h, RGB_T *scratch, AlphaT alpha) {
1089#if defined(FL_IS_AVR)
1094 for (
int x = 0;
x < w; ++
x) {
1097 const RGB_T *src = pixels +
x;
1098 RGB_T *dst = scratch + R;
1099 for (
int i = 0; i < h; ++i) {
1105 apply_pass_alpha_1ch<R>(scratch, pixels +
x, h, w, alpha);
1107 apply_pass_1ch<R>(scratch, pixels +
x, h, w);
1114 pixels, w, h, scratch, alpha);
1117 pixels, w, h, scratch, alpha);
1129template <
int hRadius,
int vRadius,
typename RGB_T,
typename AlphaT>
1132 const int w = canvas.
width;
1133 const int h = canvas.
height;
1134 if (w <= 0 || h <= 0)
1146 if (hRadius == 0 && vRadius == 0) {
1148 RGB_T *pixels = canvas.
pixels;
1149 for (
int i = 0; i < w * h; ++i) {
1150 RGB_T &p = pixels[i];
1151 p = P::make(P::ch(p.r), P::ch(p.g), P::ch(p.b), alpha);
1159 RGB_T *pad = padbuf.
data();
1160 RGB_T *pixels = canvas.
pixels;
1168 for (
int y = 0;
y < h; ++
y) {
1169 RGB_T *row = pixels +
y * w;
1172 if (vRadius == 0 && applyAlpha)
1174 pad, row, w, alpha);
1177 pad, row, w, alpha);
1185 pixels, w, h, pad, alpha);
1188 pixels, w, h, pad, alpha);
1194template <
int hRadius,
int vRadius,
typename RGB_T>
1201template <
int hRadius,
int vRadius,
typename RGB_T>
1209template <
int hRadius,
int vRadius,
typename RGB_T,
typename AlphaT>
1212 const int w = canvas.
width;
1213 const int h = canvas.
height;
1214 if (w <= 0 || h <= 0)
1231 if (hRadius == 0 && vRadius == 0) {
1233 for (
int y = 0;
y < h; ++
y) {
1234 for (
int x = 0;
x < w; ++
x) {
1235 RGB_T &p = canvas.
at(
x,
y);
1237 p = ops.make(ops.ch(p.r), ops.ch(p.g), ops.ch(p.b), alpha);
1246 RGB_T *pad = padbuf.
data();
1253 for (
int y = 0;
y < h; ++
y) {
1254 for (
int x = 0;
x < w; ++
x)
1255 pad[hRadius +
x] = canvas.
at(
x,
y);
1257 constexpr int shift = 2 * hRadius;
1258 for (
int x = 0;
x < w; ++
x) {
1262 if (vRadius == 0 && applyAlpha)
1263 result =
P().make(
static_cast<acc_t
>(r >> shift),
1264 static_cast<acc_t
>(g >> shift),
1265 static_cast<acc_t
>(b >> shift), alpha);
1267 result =
P().make(
static_cast<acc_t
>(r >> shift),
1268 static_cast<acc_t
>(g >> shift),
1269 static_cast<acc_t
>(b >> shift));
1280 for (
int x = 0;
x < w; ++
x) {
1281 for (
int y = 0;
y < h; ++
y)
1282 pad[vRadius +
y] = canvas.
at(
x,
y);
1284 constexpr int shift = 2 * vRadius;
1285 for (
int y = 0;
y < h; ++
y) {
1290 result =
P().make(
static_cast<acc_t
>(r >> shift),
1291 static_cast<acc_t
>(g >> shift),
1292 static_cast<acc_t
>(b >> shift), alpha);
1294 result =
P().make(
static_cast<acc_t
>(r >> shift),
1295 static_cast<acc_t
>(g >> shift),
1296 static_cast<acc_t
>(b >> shift));
1305template <
int hRadius,
int vRadius,
typename RGB_T>
1312template <
int hRadius,
int vRadius,
typename RGB_T>
1319#define BLUR_INST_F8(H, V, T) \
1320 template void blurGaussian<H, V, T>(Canvas<T> &, alpha8);
1332#if !defined(FL_IS_AVR)
1346#define BLUR_INST_F16(H, V, T) \
1347 template void blurGaussian<H, V, T>(Canvas<T> &, alpha16);
1359#if !defined(FL_IS_AVR)
1373#define BLUR_MAPPED_INST_F8(H, V, T) \
1374 template void blurGaussian<H, V, T>(CanvasMapped<T> &, alpha8);
1384#if !defined(FL_IS_AVR)
1394#undef BLUR_MAPPED_INST_F8
1398#define BLUR_MAPPED_INST_F16(H, V, T) \
1399 template void blurGaussian<H, V, T>(CanvasMapped<T> &, alpha16);
1409#if !defined(FL_IS_AVR)
1419#undef BLUR_MAPPED_INST_F16
FL_OPTIMIZATION_LEVEL_O3_BEGIN fl::u16 XY(fl::u8 x, fl::u8 y) FL_LINK_WEAK
static XYMap constructWithUserFunction(u16 width, u16 height, XYFunction xyFunction, u16 offset=0) FL_NOEXCEPT
bool isRectangularGrid() const FL_NOEXCEPT
const T * data() const FL_NOEXCEPT
constexpr u16 raw() const FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE u8x8 from_raw(u16 raw) FL_NOEXCEPT
fl::size size() const FL_NOEXCEPT
void resize(fl::size n) FL_NOEXCEPT
Defines the 8-bit red, green, and blue (RGB) pixel type in the fl namespace.
Legacy compatibility header for 8-bit scaling functions.
Internal FastLED header for implementation files.
void blur2d(fl::span< CRGB > leds, fl::u8 width, fl::u8 height, fract8 blur_amount, const XYMap &xymap)
Two-dimensional blur filter (span version).
void blur1d(fl::span< CRGB > leds, fract8 blur_amount)
One-dimensional blur filter (span version).
void blurRows(fl::span< CRGB > leds, fl::u8 width, fl::u8 height, fract8 blur_amount, const XYMap &xyMap)
Perform a blur1d() on every row of a rectangular matrix (span version).
void blurColumns(fl::span< CRGB > leds, fl::u8 width, fl::u8 height, fract8 blur_amount, const XYMap &xyMap)
Perform a blur1d() on every column of a rectangular matrix (span version).
Centralized logging categories for FastLED hardware interfaces and subsystems.
fl::u16 xy_legacy_wrapper(fl::u16 x, fl::u16 y, fl::u16 width, fl::u16 height)
u8 fract8
Fixed-Point Fractional Types.
typename conditional< B, T, F >::type conditional_t
static void vpass_full(RGB_T *pixels, int w, int h, RGB_T *scratch, AlphaT alpha)
static FL_OPTIMIZE_FUNCTION void vpass_rowmajor_impl(RGB_T *pixels, int w, int h, RGB_T *scratch, AlphaT alpha)
constexpr AlphaT alpha_identity()
FL_ALWAYS_INLINE void hpass_row(RGB_T *pad, RGB_T *out, int w, AlphaT alpha)
static void simd_conv_121(const u8 *FL_RESTRICT_PARAM a, const u8 *FL_RESTRICT_PARAM b, const u8 *FL_RESTRICT_PARAM c, u8 *FL_RESTRICT_PARAM out, int nbytes)
FL_NO_INLINE_IF_AVR static FL_OPTIMIZE_FUNCTION void apply_pass_alpha(const RGB_T *pad, RGB_T *out, int count, int stride, AlphaT alpha)
static void simd_conv_r3(const u8 *p0, const u8 *p1, const u8 *p2, const u8 *p3, const u8 *p4, const u8 *p5, const u8 *p6, u8 *out, int nbytes)
static fl::span< RGB_T > get_padbuf(int minSize)
static void simd_conv_14641(const u8 *p0, const u8 *p1, const u8 *p2, const u8 *p3, const u8 *p4, u8 *out, int nbytes)
static int compute_pad_size(int w, int h)
constexpr alpha8 alpha_identity< alpha8 >()
static void simd_conv_r4(const u8 *p0, const u8 *p1, const u8 *p2, const u8 *p3, const u8 *p4, const u8 *p5, const u8 *p6, const u8 *p7, const u8 *p8, u8 *out, int nbytes)
constexpr alpha16 alpha_identity< alpha16 >()
FL_NO_INLINE_IF_AVR static FL_OPTIMIZE_FUNCTION void apply_pass(const RGB_T *pad, RGB_T *out, int count, int stride)
CRGB BLUR_INST_F8(2, 2, CRGB) BLUR_INST_F8(3
void blurGaussian(Canvas< RGB_T > &canvas, alpha8 dimFactor)
Compile-time Gaussian blur with independent H/V radii.
CRGB BLUR_INST_F16(2, 2, CRGB) BLUR_INST_F16(3
FL_OPTIMIZE_FUNCTION void blurGaussianImpl(Canvas< RGB_T > &canvas, AlphaT alpha)
CRGB BLUR_MAPPED_INST_F16(2, 2, CRGB) BLUR_MAPPED_INST_F16(3
CRGB BLUR_MAPPED_INST_F8(2, 2, CRGB) BLUR_MAPPED_INST_F8(3
FL_OPTIMIZE_FUNCTION void blurGaussianMappedImpl(CanvasMapped< RGB_T > &canvas, AlphaT alpha)
FASTLED_FORCE_INLINE fl::u8 P(fl::u8 x)
expected< T, E > result
Alias for expected (Rust-style naming)
Base definition for an LED controller.
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FL_BUILTIN_MEMCPY(dest, src, n)
#define FL_NO_INLINE_IF_AVR
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FASTLED_UNUSED(x)
#define FL_OPTIMIZE_FUNCTION
#define FL_BUILTIN_MEMSET(dest, val, n)
#define FL_RESTRICT_PARAM
Umbrella header for SIMD subsystem.
CRGB & nscale8(u8 scaledown) FL_NOEXCEPT
Scale down a RGB to N/256ths of its current brightness, using "plain math" dimming rules.
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Unsigned 16-bit alpha / brightness — UNORM16.
Unsigned 8-bit alpha / brightness — UNORM8.
Simple rectangular canvas for graphics operations Combines a pixel buffer with dimensions for cache-o...
RGB_T & at(int x, int y) FL_NOEXCEPT
XYMap-backed canvas for non-rectangular or remapped layouts.
FL_ALWAYS_INLINE void apply(const RGB_T *row, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(const RGB_T *row, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(const RGB_T *row, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(const RGB_T *row, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(const RGB_T *row, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE u32 ch(u8x8 v)
FL_ALWAYS_INLINE CRGB16 make(u32 r, u32 g, u32 b, alpha16 a)
FL_ALWAYS_INLINE CRGB16 zero()
FL_ALWAYS_INLINE CRGB16 make(u32 r, u32 g, u32 b, alpha8 a)
FL_ALWAYS_INLINE CRGB16 make(u32 r, u32 g, u32 b)
FL_ALWAYS_INLINE CRGB make(u16 r, u16 g, u16 b)
FL_ALWAYS_INLINE u16 ch(u8 v)
FL_ALWAYS_INLINE CRGB make(u16 r, u16 g, u16 b, alpha16 a)
FL_ALWAYS_INLINE CRGB zero()
FL_ALWAYS_INLINE CRGB make(u16 r, u16 g, u16 b, alpha8 a)
static void apply(const u8 *pb, int, u8 *ob, int nbytes, u8 *, int)
static void apply(const u8 *pb, int S, u8 *ob, int nbytes, u8 *, int)
static void apply(const u8 *pb, int S, u8 *ob, int nbytes, u8 *, int)
static void apply(const u8 *pb, int S, u8 *ob, int nbytes, u8 *, int)
static void apply(const u8 *pb, int S, u8 *ob, int nbytes, u8 *, int)
static void apply(RGB_T **bufs, const RGB_T **, u8 *out, int nbytes)
static void apply(RGB_T **bufs, const RGB_T **fwd, u8 *out, int nbytes)
static void apply(RGB_T **bufs, const RGB_T **fwd, u8 *out, int nbytes)
static void apply(RGB_T **bufs, const RGB_T **fwd, u8 *out, int nbytes)
static void apply(RGB_T **bufs, const RGB_T **fwd, u8 *out, int nbytes)
FL_ALWAYS_INLINE void apply(RGB_T **bufs, const RGB_T **, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(RGB_T **bufs, const RGB_T **fwd, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(RGB_T **bufs, const RGB_T **fwd, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(RGB_T **bufs, const RGB_T **fwd, int x, acc_t &r, acc_t &g, acc_t &b)
FL_ALWAYS_INLINE void apply(RGB_T **bufs, const RGB_T **fwd, int x, acc_t &r, acc_t &g, acc_t &b)