FastLED 3.9.15
Loading...
Searching...
No Matches

◆ downscaleArbitrary()

void fl::downscaleArbitrary ( const CRGB * src,
const XYMap & srcXY,
CRGB * dst,
const XYMap & dstXY )

Definition at line 81 of file downscale.cpp.

82 {
83 const uint16_t srcWidth = srcXY.getWidth();
84 const uint16_t srcHeight = srcXY.getHeight();
85 const uint16_t dstWidth = dstXY.getWidth();
86 const uint16_t dstHeight = dstXY.getHeight();
87
88 const uint32_t FP_ONE = 256; // Q8.8 fixed-point multiplier
89
90 FASTLED_ASSERT(dstWidth <= srcWidth,
91 "Destination width must be <= source width");
92 FASTLED_ASSERT(dstHeight <= srcHeight,
93 "Destination height must be <= source height");
94
95 for (uint16_t dy = 0; dy < dstHeight; ++dy) {
96 // Fractional boundaries in Q8.8
97 uint32_t dstY0 = (dy * srcHeight * FP_ONE) / dstHeight;
98 uint32_t dstY1 = ((dy + 1) * srcHeight * FP_ONE) / dstHeight;
99
100 for (uint16_t dx = 0; dx < dstWidth; ++dx) {
101 uint32_t dstX0 = (dx * srcWidth * FP_ONE) / dstWidth;
102 uint32_t dstX1 = ((dx + 1) * srcWidth * FP_ONE) / dstWidth;
103
104 uint64_t rSum = 0, gSum = 0, bSum = 0;
105 uint32_t totalWeight = 0;
106
107 // Find covered source pixels
108 uint16_t srcY_start = dstY0 / FP_ONE;
109 uint16_t srcY_end = (dstY1 + FP_ONE - 1) / FP_ONE; // ceil
110
111 uint16_t srcX_start = dstX0 / FP_ONE;
112 uint16_t srcX_end = (dstX1 + FP_ONE - 1) / FP_ONE; // ceil
113
114 for (uint16_t sy = srcY_start; sy < srcY_end; ++sy) {
115 // Calculate vertical overlap in Q8.8
116 uint32_t sy0 = sy * FP_ONE;
117 uint32_t sy1 = (sy + 1) * FP_ONE;
118 uint32_t y_overlap = MIN(dstY1, sy1) - MAX(dstY0, sy0);
119 if (y_overlap == 0)
120 continue;
121
122 for (uint16_t sx = srcX_start; sx < srcX_end; ++sx) {
123 uint32_t sx0 = sx * FP_ONE;
124 uint32_t sx1 = (sx + 1) * FP_ONE;
125 uint32_t x_overlap = MIN(dstX1, sx1) - MAX(dstX0, sx0);
126 if (x_overlap == 0)
127 continue;
128
129 uint32_t weight = (x_overlap * y_overlap + (FP_ONE >> 1)) >>
130 8; // Q8.8 * Q8.8 → Q16.16 → Q8.8
131
132 const CRGB &p = src[srcXY.mapToIndex(sx, sy)];
133 rSum += p.r * weight;
134 gSum += p.g * weight;
135 bSum += p.b * weight;
136 totalWeight += weight;
137 }
138 }
139
140 // Final division, rounding
141 uint8_t r =
142 totalWeight ? (rSum + (totalWeight >> 1)) / totalWeight : 0;
143 uint8_t g =
144 totalWeight ? (gSum + (totalWeight >> 1)) / totalWeight : 0;
145 uint8_t b =
146 totalWeight ? (bSum + (totalWeight >> 1)) / totalWeight : 0;
147
148 dst[dstXY.mapToIndex(dx, dy)] = CRGB(r, g, b);
149 }
150 }
151}
uint16_t getWidth() const
Definition xymap.cpp:124
uint16_t mapToIndex(const uint16_t &x, const uint16_t &y) const
Definition xymap.cpp:97
uint16_t getHeight() const
Definition xymap.cpp:126
#define MIN(a, b)
Definition math_macros.h:15
#define MAX(a, b)
Definition math_macros.h:11
static FASTLED_NAMESPACE_BEGIN uint8_t const p[]
Definition noise.cpp:30
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:55

References fl::XYMap::getHeight(), fl::XYMap::getWidth(), fl::XYMap::mapToIndex(), MAX, MIN, and p.

Referenced by downscale().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: