Files
wrobot/v1.2/Shibo-main-TOMMY/lib/FastLED/src/fl/blur.cpp
T

135 lines
4.0 KiB
C++

#include "fl/stdint.h"
#define FASTLED_INTERNAL
#include "FastLED.h"
#include "crgb.h"
#include "fl/blur.h"
#include "fl/colorutils_misc.h"
#include "fl/compiler_control.h"
#include "fl/deprecated.h"
#include "fl/unused.h"
#include "fl/xymap.h"
#include "lib8tion/scale8.h"
#include "fl/int.h"
namespace fl {
// Legacy XY function. This is a weak symbol that can be overridden by the user.
fl::u16 XY(fl::u8 x, fl::u8 y) FL_LINK_WEAK;
FL_LINK_WEAK fl::u16 XY(fl::u8 x, fl::u8 y) {
FASTLED_UNUSED(x);
FASTLED_UNUSED(y);
FASTLED_ASSERT(false, "the user didn't provide an XY function");
return 0;
}
// fl::u16 XY(fl::u8 x, fl::u8 y) {
// return 0;
// }
// make this a weak symbol
namespace {
fl::u16 xy_legacy_wrapper(fl::u16 x, fl::u16 y, fl::u16 width,
fl::u16 height) {
FASTLED_UNUSED(width);
FASTLED_UNUSED(height);
return XY(x, y);
}
} // namespace
// blur1d: one-dimensional blur filter. Spreads light to 2 line neighbors.
// blur2d: two-dimensional blur filter. Spreads light to 8 XY neighbors.
//
// 0 = no spread at all
// 64 = moderate spreading
// 172 = maximum smooth, even spreading
//
// 173..255 = wider spreading, but increasing flicker
//
// Total light is NOT entirely conserved, so many repeated
// calls to 'blur' will also result in the light fading,
// eventually all the way to black; this is by design so that
// it can be used to (slowly) clear the LEDs to black.
void blur1d(CRGB *leds, fl::u16 numLeds, fract8 blur_amount) {
fl::u8 keep = 255 - blur_amount;
fl::u8 seep = blur_amount >> 1;
CRGB carryover = CRGB::Black;
for (fl::u16 i = 0; i < numLeds; ++i) {
CRGB cur = leds[i];
CRGB part = cur;
part.nscale8(seep);
cur.nscale8(keep);
cur += carryover;
if (i)
leds[i - 1] += part;
leds[i] = cur;
carryover = part;
}
}
void blur2d(CRGB *leds, fl::u8 width, fl::u8 height, fract8 blur_amount,
const XYMap &xymap) {
blurRows(leds, width, height, blur_amount, xymap);
blurColumns(leds, width, height, blur_amount, xymap);
}
void blur2d(CRGB *leds, fl::u8 width, fl::u8 height, fract8 blur_amount) {
XYMap xy =
XYMap::constructWithUserFunction(width, height, xy_legacy_wrapper);
blur2d(leds, width, height, blur_amount, xy);
}
void blurRows(CRGB *leds, fl::u8 width, fl::u8 height, fract8 blur_amount,
const XYMap &xyMap) {
/* for( fl::u8 row = 0; row < height; row++) {
CRGB* rowbase = leds + (row * width);
blur1d( rowbase, width, blur_amount);
}
*/
// blur rows same as columns, for irregular matrix
fl::u8 keep = 255 - blur_amount;
fl::u8 seep = blur_amount >> 1;
for (fl::u8 row = 0; row < height; row++) {
CRGB carryover = CRGB::Black;
for (fl::u8 i = 0; i < width; i++) {
CRGB cur = leds[xyMap.mapToIndex(i, row)];
CRGB part = cur;
part.nscale8(seep);
cur.nscale8(keep);
cur += carryover;
if (i)
leds[xyMap.mapToIndex(i - 1, row)] += part;
leds[xyMap.mapToIndex(i, row)] = cur;
carryover = part;
}
}
}
// blurColumns: perform a blur1d on each column of a rectangular matrix
void blurColumns(CRGB *leds, fl::u8 width, fl::u8 height, fract8 blur_amount,
const XYMap &xyMap) {
// blur columns
fl::u8 keep = 255 - blur_amount;
fl::u8 seep = blur_amount >> 1;
for (fl::u8 col = 0; col < width; ++col) {
CRGB carryover = CRGB::Black;
for (fl::u8 i = 0; i < height; ++i) {
CRGB cur = leds[xyMap.mapToIndex(col, i)];
CRGB part = cur;
part.nscale8(seep);
cur.nscale8(keep);
cur += carryover;
if (i)
leds[xyMap.mapToIndex(col, i - 1)] += part;
leds[xyMap.mapToIndex(col, i)] = cur;
carryover = part;
}
}
}
} // namespace fl