20 u16 inputHeight, u16 outputWidth, u16 outputHeight) {
21 const u16 scale_factor = 256;
23 for (u16
y = 0;
y < outputHeight;
y++) {
24 for (u16
x = 0;
x < outputWidth;
x++) {
26 u32 fx = ((u32)
x * (inputWidth - 1) * scale_factor) /
28 u32 fy = ((u32)
y * (inputHeight - 1) * scale_factor) /
31 u16 ix = fx / scale_factor;
32 u16 iy = fy / scale_factor;
33 u16 dx = fx % scale_factor;
34 u16 dy = fy % scale_factor;
36 u16 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
37 u16 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
40 u16 i00 = iy * inputWidth + ix;
41 u16 i10 = iy * inputWidth + ix1;
42 u16 i01 = iy1 * inputWidth + ix;
43 u16 i11 = iy1 * inputWidth + ix1;
45 CRGB c00 = input[i00];
46 CRGB c10 = input[i10];
47 CRGB c01 = input[i01];
48 CRGB c11 = input[i11];
56 u16 idx =
y * outputWidth +
x;
63 u8 inputHeight,
u8 outputWidth,
u8 outputHeight) {
64 for (
u8 y = 0;
y < outputHeight;
y++) {
65 for (
u8 x = 0;
x < outputWidth;
x++) {
68 u16 fx = ((u16)
x * (inputWidth - 1) * 256) / (outputWidth - 1);
69 u16 fy = ((u16)
y * (inputHeight - 1) * 256) / (outputHeight - 1);
76 u8 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
77 u8 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
80 u16 i00 = iy * inputWidth + ix;
81 u16 i10 = iy * inputWidth + ix1;
82 u16 i01 = iy1 * inputWidth + ix;
83 u16 i11 = iy1 * inputWidth + ix1;
85 CRGB c00 = input[i00];
86 CRGB c10 = input[i10];
87 CRGB c01 = input[i01];
88 CRGB c11 = input[i11];
99 u16 idx =
y * outputWidth +
x;
107 u16 n =
xyMap.getTotal();
108 u16 outputWidth =
xyMap.getWidth();
109 u16 outputHeight =
xyMap.getHeight();
110 const u16 scale_factor = 256;
112 for (u16
y = 0;
y < outputHeight;
y++) {
113 for (u16
x = 0;
x < outputWidth;
x++) {
115 u32 fx = ((u32)
x * (inputWidth - 1) * scale_factor) /
117 u32 fy = ((u32)
y * (inputHeight - 1) * scale_factor) /
120 u16 ix = fx / scale_factor;
121 u16 iy = fy / scale_factor;
122 u16 dx = fx % scale_factor;
123 u16 dy = fy % scale_factor;
125 u16 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
126 u16 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
128 u16 i00 = iy * inputWidth + ix;
129 u16 i10 = iy * inputWidth + ix1;
130 u16 i01 = iy1 * inputWidth + ix;
131 u16 i11 = iy1 * inputWidth + ix1;
133 CRGB c00 = input[i00];
134 CRGB c10 = input[i10];
135 CRGB c01 = input[i01];
136 CRGB c11 = input[i11];
143 u16 idx =
xyMap.mapToIndex(
x,
y);
152 u16 dx_inv = 256 - dx;
153 u16 dy_inv = 256 - dy;
155 u32 w00 = (u32)dx_inv * dy_inv;
156 u32 w10 = (u32)dx * dy_inv;
157 u32 w01 = (u32)dx_inv * dy;
158 u32 w11 = (u32)dx * dy;
160 u32 sum = v00 * w00 + v10 * w10 + v01 * w01 + v11 * w11;
177 u16 n =
xyMap.getTotal();
183 u16 fx = ((u16)
x * (inputWidth - 1) * 256) / (
width - 1);
185 ((u16)
y * (inputHeight - 1) * 256) / (
height - 1);
192 u8 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
193 u8 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
195 u16 i00 = iy * inputWidth + ix;
196 u16 i10 = iy * inputWidth + ix1;
197 u16 i01 = iy1 * inputWidth + ix;
198 u16 i11 = iy1 * inputWidth + ix1;
200 CRGB c00 = input[i00];
201 CRGB c10 = input[i10];
202 CRGB c01 = input[i01];
203 CRGB c11 = input[i11];
213 u16 idx =
xyMap.mapToIndex(
x,
y);
223 u16 dx_inv = 256 - dx;
224 u16 dy_inv = 256 - dy;
227 u16 w00 = (dx_inv * dy_inv) >> 8;
228 u16 w10 = (dx * dy_inv) >> 8;
229 u16 w01 = (dx_inv * dy) >> 8;
230 u16 w11 = (dx * dy) >> 8;
233 u16 weight_sum = w00 + w10 + w01 + w11;
236 u16 sum = v00 * w00 + v10 * w10 + v01 * w01 + v11 * w11;
239 u8 result = (sum + (weight_sum >> 1)) / weight_sum;
246 u8 v11,
float dx,
float dy) {
247 float dx_inv = 1.0f - dx;
248 float dy_inv = 1.0f - dy;
251 float w00 = dx_inv * dy_inv;
252 float w10 = dx * dy_inv;
253 float w01 = dx_inv * dy;
257 float sum = v00 * w00 + v10 * w10 + v01 * w01 + v11 * w11;
268 u16 n =
xyMap.getTotal();
269 u16 outputWidth =
xyMap.getWidth();
270 u16 outputHeight =
xyMap.getHeight();
272 for (u16
y = 0;
y < outputHeight;
y++) {
273 for (u16
x = 0;
x < outputWidth;
x++) {
276 static_cast<float>(
x) * (inputWidth - 1) / (outputWidth - 1);
278 static_cast<float>(
y) * (inputHeight - 1) / (outputHeight - 1);
280 u16 ix =
static_cast<u16
>(fx);
281 u16 iy =
static_cast<u16
>(fy);
285 u16 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
286 u16 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
288 u16 i00 = iy * inputWidth + ix;
289 u16 i10 = iy * inputWidth + ix1;
290 u16 i01 = iy1 * inputWidth + ix;
291 u16 i11 = iy1 * inputWidth + ix1;
293 CRGB c00 = input[i00];
294 CRGB c10 = input[i10];
295 CRGB c01 = input[i01];
296 CRGB c11 = input[i11];
306 u16 idx =
xyMap.mapToIndex(
x,
y);
317 u8 outputWidth =
xyMap.getWidth();
318 u8 outputHeight =
xyMap.getHeight();
319 if (outputWidth !=
xyMap.getWidth() || outputHeight !=
xyMap.getHeight()) {
323 u16 n =
xyMap.getTotal();
325 for (
u8 y = 0;
y < outputHeight;
y++) {
326 for (
u8 x = 0;
x < outputWidth;
x++) {
329 static_cast<float>(
x) * (inputWidth - 1) / (outputWidth - 1);
331 static_cast<float>(
y) * (inputHeight - 1) / (outputHeight - 1);
333 u8 ix =
static_cast<u8>(fx);
334 u8 iy =
static_cast<u8>(fy);
338 u8 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
339 u8 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
341 u16 i00 = iy * inputWidth + ix;
342 u16 i10 = iy * inputWidth + ix1;
343 u16 i01 = iy1 * inputWidth + ix;
344 u16 i11 = iy1 * inputWidth + ix1;
346 CRGB c00 = input[i00];
347 CRGB c10 = input[i10];
348 CRGB c01 = input[i01];
349 CRGB c11 = input[i11];
359 u16 idx =
xyMap.mapToIndex(
x,
y);
Defines the 8-bit red, green, and blue (RGB) pixel type in the fl namespace.
void upscaleRectangular(const CRGB *input, CRGB *output, u16 inputWidth, u16 inputHeight, u16 outputWidth, u16 outputHeight)
Optimized upscale for rectangular/line-by-line XY maps.
void upscaleRectangularPowerOf2(const CRGB *input, CRGB *output, u8 inputWidth, u8 inputHeight, u8 outputWidth, u8 outputHeight)
Optimized upscale for rectangular/line-by-line XY maps (power-of-2 version).
u8 bilinearInterpolatePowerOf2(u8 v00, u8 v10, u8 v01, u8 v11, u8 dx, u8 dy)
void upscaleArbitraryFloat(const CRGB *input, CRGB *output, u16 inputWidth, u16 inputHeight, const XYMap &xyMap)
void upscaleArbitrary(const CRGB *input, CRGB *output, u16 inputWidth, u16 inputHeight, const XYMap &xyMap)
Performs bilinear interpolation for upscaling an image.
expected< T, E > result
Alias for expected (Rust-style naming)
u8 bilinearInterpolate(u8 v00, u8 v10, u8 v01, u8 v11, u16 dx, u16 dy)
u8 upscaleFloat(u8 v00, u8 v10, u8 v01, u8 v11, float dx, float dy)
void upscalePowerOf2(const CRGB *input, CRGB *output, u8 inputWidth, u8 inputHeight, const XYMap &xyMap)
Performs bilinear interpolation for upscaling an image.
Base definition for an LED controller.
Representation of an 8-bit RGB pixel (Red, Green, Blue)