21 u16 inputHeight, u16 outputWidth, u16 outputHeight) {
22 const u16 scale_factor = 256;
24 for (u16
y = 0;
y < outputHeight;
y++) {
25 for (u16
x = 0;
x < outputWidth;
x++) {
27 u32 fx = ((u32)
x * (inputWidth - 1) * scale_factor) /
29 u32 fy = ((u32)
y * (inputHeight - 1) * scale_factor) /
32 u16 ix = fx / scale_factor;
33 u16 iy = fy / scale_factor;
34 u16 dx = fx % scale_factor;
35 u16 dy = fy % scale_factor;
37 u16 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
38 u16 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
41 u16 i00 = iy * inputWidth + ix;
42 u16 i10 = iy * inputWidth + ix1;
43 u16 i01 = iy1 * inputWidth + ix;
44 u16 i11 = iy1 * inputWidth + ix1;
46 CRGB c00 = input[i00];
47 CRGB c10 = input[i10];
48 CRGB c01 = input[i01];
49 CRGB c11 = input[i11];
57 u16 idx =
y * outputWidth +
x;
64 u8 inputHeight,
u8 outputWidth,
u8 outputHeight) {
65 for (
u8 y = 0;
y < outputHeight;
y++) {
66 for (
u8 x = 0;
x < outputWidth;
x++) {
69 u16 fx = ((u16)
x * (inputWidth - 1) * 256) / (outputWidth - 1);
70 u16 fy = ((u16)
y * (inputHeight - 1) * 256) / (outputHeight - 1);
77 u8 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
78 u8 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
81 u16 i00 = iy * inputWidth + ix;
82 u16 i10 = iy * inputWidth + ix1;
83 u16 i01 = iy1 * inputWidth + ix;
84 u16 i11 = iy1 * inputWidth + ix1;
86 CRGB c00 = input[i00];
87 CRGB c10 = input[i10];
88 CRGB c01 = input[i01];
89 CRGB c11 = input[i11];
100 u16 idx =
y * outputWidth +
x;
108 u16 n =
xyMap.getTotal();
109 u16 outputWidth =
xyMap.getWidth();
110 u16 outputHeight =
xyMap.getHeight();
111 const u16 scale_factor = 256;
113 for (u16
y = 0;
y < outputHeight;
y++) {
114 for (u16
x = 0;
x < outputWidth;
x++) {
116 u32 fx = ((u32)
x * (inputWidth - 1) * scale_factor) /
118 u32 fy = ((u32)
y * (inputHeight - 1) * scale_factor) /
121 u16 ix = fx / scale_factor;
122 u16 iy = fy / scale_factor;
123 u16 dx = fx % scale_factor;
124 u16 dy = fy % scale_factor;
126 u16 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
127 u16 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
129 u16 i00 = iy * inputWidth + ix;
130 u16 i10 = iy * inputWidth + ix1;
131 u16 i01 = iy1 * inputWidth + ix;
132 u16 i11 = iy1 * inputWidth + ix1;
134 CRGB c00 = input[i00];
135 CRGB c10 = input[i10];
136 CRGB c01 = input[i01];
137 CRGB c11 = input[i11];
144 u16 idx =
xyMap.mapToIndex(
x,
y);
153 u16 dx_inv = 256 - dx;
154 u16 dy_inv = 256 - dy;
156 u32 w00 = (u32)dx_inv * dy_inv;
157 u32 w10 = (u32)dx * dy_inv;
158 u32 w01 = (u32)dx_inv * dy;
159 u32 w11 = (u32)dx * dy;
161 u32 sum = v00 * w00 + v10 * w10 + v01 * w01 + v11 * w11;
174 if (width !=
xyMap.getWidth() || height !=
xyMap.getHeight()) {
178 u16 n =
xyMap.getTotal();
180 for (
u8 y = 0;
y < height;
y++) {
181 for (
u8 x = 0;
x < width;
x++) {
184 u16 fx = ((u16)
x * (inputWidth - 1) * 256) / (width - 1);
186 ((u16)
y * (inputHeight - 1) * 256) / (height - 1);
193 u8 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
194 u8 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
196 u16 i00 = iy * inputWidth + ix;
197 u16 i10 = iy * inputWidth + ix1;
198 u16 i01 = iy1 * inputWidth + ix;
199 u16 i11 = iy1 * inputWidth + ix1;
201 CRGB c00 = input[i00];
202 CRGB c10 = input[i10];
203 CRGB c01 = input[i01];
204 CRGB c11 = input[i11];
214 u16 idx =
xyMap.mapToIndex(
x,
y);
224 u16 dx_inv = 256 - dx;
225 u16 dy_inv = 256 - dy;
228 u16 w00 = (dx_inv * dy_inv) >> 8;
229 u16 w10 = (dx * dy_inv) >> 8;
230 u16 w01 = (dx_inv * dy) >> 8;
231 u16 w11 = (dx * dy) >> 8;
234 u16 weight_sum = w00 + w10 + w01 + w11;
237 u16 sum = v00 * w00 + v10 * w10 + v01 * w01 + v11 * w11;
240 u8 result = (sum + (weight_sum >> 1)) / weight_sum;
247 u8 v11,
float dx,
float dy) {
248 float dx_inv = 1.0f - dx;
249 float dy_inv = 1.0f - dy;
252 float w00 = dx_inv * dy_inv;
253 float w10 = dx * dy_inv;
254 float w01 = dx_inv * dy;
258 float sum = v00 * w00 + v10 * w10 + v01 * w01 + v11 * w11;
269 u16 n =
xyMap.getTotal();
270 u16 outputWidth =
xyMap.getWidth();
271 u16 outputHeight =
xyMap.getHeight();
273 for (u16
y = 0;
y < outputHeight;
y++) {
274 for (u16
x = 0;
x < outputWidth;
x++) {
277 static_cast<float>(
x) * (inputWidth - 1) / (outputWidth - 1);
279 static_cast<float>(
y) * (inputHeight - 1) / (outputHeight - 1);
281 u16 ix =
static_cast<u16
>(fx);
282 u16 iy =
static_cast<u16
>(fy);
286 u16 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
287 u16 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
289 u16 i00 = iy * inputWidth + ix;
290 u16 i10 = iy * inputWidth + ix1;
291 u16 i01 = iy1 * inputWidth + ix;
292 u16 i11 = iy1 * inputWidth + ix1;
294 CRGB c00 = input[i00];
295 CRGB c10 = input[i10];
296 CRGB c01 = input[i01];
297 CRGB c11 = input[i11];
307 u16 idx =
xyMap.mapToIndex(
x,
y);
318 u8 outputWidth =
xyMap.getWidth();
319 u8 outputHeight =
xyMap.getHeight();
320 if (outputWidth !=
xyMap.getWidth() || outputHeight !=
xyMap.getHeight()) {
324 u16 n =
xyMap.getTotal();
326 for (
u8 y = 0;
y < outputHeight;
y++) {
327 for (
u8 x = 0;
x < outputWidth;
x++) {
330 static_cast<float>(
x) * (inputWidth - 1) / (outputWidth - 1);
332 static_cast<float>(
y) * (inputHeight - 1) / (outputHeight - 1);
334 u8 ix =
static_cast<u8>(fx);
335 u8 iy =
static_cast<u8>(fy);
339 u8 ix1 = (ix + 1 < inputWidth) ? ix + 1 : ix;
340 u8 iy1 = (iy + 1 < inputHeight) ? iy + 1 : iy;
342 u16 i00 = iy * inputWidth + ix;
343 u16 i10 = iy * inputWidth + ix1;
344 u16 i01 = iy1 * inputWidth + ix;
345 u16 i11 = iy1 * inputWidth + ix1;
347 CRGB c00 = input[i00];
348 CRGB c10 = input[i10];
349 CRGB c01 = input[i01];
350 CRGB c11 = input[i11];
360 u16 idx =
xyMap.mapToIndex(
x,
y);
Result type for promise operations.
Defines the red, green, and blue (RGB) pixel struct.
Implements the FastLED namespace macros.
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.
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.
Representation of an RGB pixel (Red, Green, Blue)