GCC Code Coverage Report


Directory: ./
File: channeloutput/PanelMatrix.cpp
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 191 300 63.7%
Functions: 8 10 80.0%
Branches: 128 248 51.6%

Line Branch Exec Source
1 /*
2 * This file is part of the Falcon Player (FPP) and is Copyright (C)
3 * 2013-2022 by the Falcon Player Developers.
4 *
5 * The Falcon Player (FPP) is free software, and is covered under
6 * multiple Open Source licenses. Please see the included 'LICENSES'
7 * file for descriptions of what files are covered by each license.
8 *
9 * This source file is covered under the LGPL v2.1 as described in the
10 * included LICENSE.LGPL file.
11 */
12
13 #include "fpp-pch.h"
14
15 #include "../common.h"
16 #include "../log.h"
17
18 #include "../Sequence.h"
19 #include "PanelMatrix.h"
20
21 118 PanelMatrix::PanelMatrix(int panelWidth, int panelHeight, int invertedData) :
22 118 m_width(0),
23 118 m_height(0),
24 118 m_outputCount(0),
25 118 m_pixelCount(0),
26 118 m_panelCount(0),
27 118 m_panelWidth(panelWidth),
28 118 m_panelHeight(panelHeight),
29
2/2
✓ Branch 0 taken 67968 times.
✓ Branch 1 taken 118 times.
68086 m_invertedData(invertedData) {
30 118 }
31
32
3/6
✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 118 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 118 times.
✗ Branch 5 not taken.
73986 PanelMatrix::~PanelMatrix() {
33
6/6
✓ Branch 0 taken 67968 times.
✓ Branch 1 taken 118 times.
✓ Branch 2 taken 2832 times.
✓ Branch 3 taken 118 times.
✓ Branch 4 taken 2832 times.
✓ Branch 5 taken 118 times.
74001 }
34
35 ✗ int PanelMatrix::ConfigurePanels(std::string layout) {
36 ✗ int result = 1;
37
38 ✗ LogDebug(VB_CHANNELOUT, "Parsing Config: '%s'\n", layout.c_str());
39
40 ✗ std::vector<std::string> panels = split(layout, '|');
41
42 ✗ for (int i = 0; i < panels.size(); i++) {
43 ✗ result &= AddPanel(panels[i]);
44 }
45
46 ✗ if (result)
47 ✗ CalculateMaps();
48
49 ✗ return result;
50 ✗ }
51
52 ✗ int PanelMatrix::AddPanel(std::string config) {
53 ✗ int output = 0;
54 ✗ int chain = 0;
55 ✗ int xOffset = 0;
56 ✗ int yOffset = 0;
57 ✗ char orientation = 'N';
58
59 ✗ std::vector<std::string> elems = split(config, ':');
60
61 ✗ if (elems.size() == 5) {
62 ✗ output = atoi(elems[0].c_str());
63 ✗ chain = atoi(elems[1].c_str());
64 ✗ xOffset = atoi(elems[3].c_str());
65 ✗ yOffset = atoi(elems[4].c_str());
66
67 ✗ if (elems[2].size())
68 ✗ orientation = elems[2].c_str()[0];
69 } else {
70 ✗ LogErr(VB_CHANNELOUT, "Invalid Panel Config: '%s'\n", config.c_str());
71 ✗ return 0;
72 }
73
74 ✗ return AddPanel(output, chain, orientation, xOffset, yOffset);
75 ✗ }
76
77 150 int PanelMatrix::AddPanel(int output, int chain, char orientation,
78 int xOffset, int yOffset, FPPColorOrder colorOrder) {
79 150 int pWidth = m_panelWidth;
80 150 int pHeight = m_panelHeight;
81
82 // These come straight from the config. The UI only produces valid ones,
83 // but out of range they index m_outputPanels and the drivers' per-output
84 // tables, and a negative offset puts pixels before the frame.
85
6/10
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 150 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 149 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 149 times.
✗ Branch 9 not taken.
150 if (output < 0 || output >= MAX_MATRIX_OUTPUTS || chain < 0 || chain >= MAX_PANELS_PER_OUTPUT ||
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
149 xOffset < 0 || yOffset < 0) {
87 1 LogErr(VB_CHANNELOUT, "Invalid panel: output %d, chain %d, offset %d,%d\n", output, chain, xOffset, yOffset);
88 1 return 0;
89 }
90
91 // Orientation, Left, Right, Normal, Upside down
92
2/4
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 149 times.
149 if ((orientation == 'L') || (orientation == 'R')) {
93 ✗ pWidth = m_panelHeight;
94 ✗ pHeight = m_panelWidth;
95
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 146 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
149 } else if ((orientation != 'N') && (orientation != 'U')) {
96 1 LogErr(VB_CHANNELOUT, "Invalid orientation '%c'\n",
97 orientation);
98 1 return 0;
99 }
100
101 // Nor may an offset grow the matrix past what the channel buffer holds:
102 // m_width * m_height * 3 is the outputs' channel count, and offsets in
103 // the millions overflowed it (and the pixel maps sized from it).
104 148 int64_t newWidth = std::max<int64_t>(m_width, (int64_t)xOffset + pWidth);
105 148 int64_t newHeight = std::max<int64_t>(m_height, (int64_t)yOffset + pHeight);
106
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 147 times.
148 if (newWidth * newHeight * 3 > (int64_t)FPPD_MAX_CHANNELS) {
107 1 LogErr(VB_CHANNELOUT, "Invalid panel: offset %d,%d makes the matrix %lldx%lld, more than %d channels\n",
108 xOffset, yOffset, (long long)newWidth, (long long)newHeight, FPPD_MAX_CHANNELS);
109 1 return 0;
110 }
111
112
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 8 times.
147 if ((xOffset + pWidth) > m_width) {
113 139 m_width = xOffset + pWidth;
114 139 m_pixelCount = m_width * m_height;
115 }
116
117
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 23 times.
147 if ((yOffset + pHeight) > m_height) {
118 124 m_height = yOffset + pHeight;
119 124 m_pixelCount = m_width * m_height;
120 }
121
122
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 141 times.
147 if (output > m_outputCount)
123 6 m_outputCount = output;
124
125
3/6
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 147 times.
✗ Branch 5 not taken.
294 if ((m_panelCount < MAX_MATRIX_PANELS) &&
126 147 (m_outputPanels[output].size() < MAX_PANELS_PER_OUTPUT)) {
127 147 m_panels[m_panelCount].output = output;
128 147 m_panels[m_panelCount].chain = chain;
129 147 m_panels[m_panelCount].width = pWidth;
130 147 m_panels[m_panelCount].height = pHeight;
131 147 m_panels[m_panelCount].orientation = orientation;
132 147 m_panels[m_panelCount].xOffset = xOffset;
133 147 m_panels[m_panelCount].yOffset = yOffset;
134 147 m_panels[m_panelCount].colorOrder = colorOrder;
135
136 147 m_panels[m_panelCount].pixelMap.resize(pWidth * pHeight * 3);
137
138 147 m_outputPanels[output].push_back(m_panelCount);
139
140
2/4
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
147 LogDebug(VB_CHANNELOUT, "Added Panel %d of size %dx%d at %dx%d facing '%c'. Color Order: %s (%d). Matrix size now: %dx%d. Panel Count: %d, Output: %d, Chain: %d\n",
141 m_panelCount, pWidth, pHeight, xOffset, yOffset, orientation, ColorOrderToString(colorOrder).c_str(), (int)colorOrder, m_width, m_height, m_panelCount, output, chain);
142 147 m_panelCount++;
143 }
144
145 147 CalculateMaps();
146
147 147 return 1;
148 }
149
150 147 int PanelMatrix::CalculateMaps(void) {
151 147 LogDebug(VB_CHANNELOUT, "PanelMatrix::CalculateMaps(), %d panels\n",
152 m_panelCount);
153
154
2/2
✓ Branch 0 taken 305 times.
✓ Branch 1 taken 147 times.
452 for (int panel = 0; panel < m_panelCount; panel++) {
155 305 int mOffset = 0;
156 305 int pOffset = 0;
157 305 int xOffset = m_panels[panel].xOffset;
158 305 int yOffset = m_panels[panel].yOffset;
159 305 int pWidth = m_panels[panel].width;
160 305 int pHeight = m_panels[panel].height;
161
162 305 FPPColorOrder colorOrder = m_panels[panel].colorOrder;
163
164 // LogDebug(VB_CHANNELOUT, "P: %d, O: %c, Pos: %dx%d, w: %d, h: %d\n", panel, m_panels[panel].orientation, xOffset, yOffset, pWidth, pHeight);
165
1/2
✓ Branch 0 taken 305 times.
✗ Branch 1 not taken.
305 m_panels[panel].pixelMap.resize(pWidth * pHeight * 3);
166
167
2/2
✓ Branch 0 taken 5832 times.
✓ Branch 1 taken 305 times.
6137 for (int y = 0; y < pHeight; y++) {
168
2/2
✓ Branch 0 taken 247936 times.
✓ Branch 1 taken 5832 times.
253768 for (int x = 0; x < pWidth; x++) {
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 247936 times.
247936 if (m_invertedData)
170 ✗ mOffset = (((m_height - (yOffset + y) - 1) * m_width) + (xOffset + x));
171 else
172 247936 mOffset = (((yOffset + y) * m_width) + (xOffset + x));
173
174
2/5
✓ Branch 0 taken 245888 times.
✓ Branch 1 taken 2048 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
247936 switch (m_panels[panel].orientation) {
175 245888 case 'N':
176 245888 pOffset = (y * pWidth) + x;
177 245888 break;
178 2048 case 'U':
179 2048 pOffset = (pWidth * pHeight) - ((y * pWidth) + x) - 1;
180 2048 break;
181 ✗ case 'L':
182 ✗ pOffset = (x * pHeight) + (pHeight - y - 1);
183 ✗ break;
184 ✗ case 'R':
185 ✗ pOffset = ((pWidth - x - 1) * pHeight) + y;
186 ✗ break;
187 }
188
189 247936 mOffset *= 3;
190 247936 pOffset *= 3;
191
192
2/2
✓ Branch 0 taken 244352 times.
✓ Branch 1 taken 3584 times.
247936 if (colorOrder == FPPColorOrder::kColorOrderRGB) {
193 244352 m_panels[panel].pixelMap[pOffset] = mOffset;
194 244352 m_panels[panel].pixelMap[pOffset + 1] = mOffset + 1;
195 244352 m_panels[panel].pixelMap[pOffset + 2] = mOffset + 2;
196
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 3072 times.
3584 } else if (colorOrder == FPPColorOrder::kColorOrderRBG) {
197 512 m_panels[panel].pixelMap[pOffset] = mOffset;
198 512 m_panels[panel].pixelMap[pOffset + 2] = mOffset + 1;
199 512 m_panels[panel].pixelMap[pOffset + 1] = mOffset + 2;
200
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 1536 times.
3072 } else if (colorOrder == FPPColorOrder::kColorOrderGRB) {
201 1536 m_panels[panel].pixelMap[pOffset + 1] = mOffset;
202 1536 m_panels[panel].pixelMap[pOffset] = mOffset + 1;
203 1536 m_panels[panel].pixelMap[pOffset + 2] = mOffset + 2;
204
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1024 times.
1536 } else if (colorOrder == FPPColorOrder::kColorOrderGBR) {
205 512 m_panels[panel].pixelMap[pOffset + 2] = mOffset;
206 512 m_panels[panel].pixelMap[pOffset] = mOffset + 1;
207 512 m_panels[panel].pixelMap[pOffset + 1] = mOffset + 2;
208
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 512 times.
1024 } else if (colorOrder == FPPColorOrder::kColorOrderBRG) {
209 512 m_panels[panel].pixelMap[pOffset + 1] = mOffset;
210 512 m_panels[panel].pixelMap[pOffset + 2] = mOffset + 1;
211 512 m_panels[panel].pixelMap[pOffset] = mOffset + 2;
212
1/2
✓ Branch 0 taken 512 times.
✗ Branch 1 not taken.
512 } else if (colorOrder == FPPColorOrder::kColorOrderBGR) {
213 512 m_panels[panel].pixelMap[pOffset + 2] = mOffset;
214 512 m_panels[panel].pixelMap[pOffset + 1] = mOffset + 1;
215 512 m_panels[panel].pixelMap[pOffset] = mOffset + 2;
216 } else // Assume RGB if somehow invalid
217 {
218 ✗ m_panels[panel].pixelMap[pOffset] = mOffset;
219 ✗ m_panels[panel].pixelMap[pOffset + 1] = mOffset + 1;
220 ✗ m_panels[panel].pixelMap[pOffset + 2] = mOffset + 2;
221 }
222 }
223 }
224 }
225
226 147 return 1;
227 }
228
229 560 void LEDPanel::drawTestPattern(unsigned char* channelData, int cycleNum, float percentOfCycle, int testType) {
230 // Test types match the ids the pixel-string test dropdown uses so the UIs
231 // can present a consistent list: 1 = panel layout/ID pattern, 4-7 =
232 // red/green/blue/white fades. Anything else draws the layout pattern.
233
3/4
✓ Branch 0 taken 482 times.
✓ Branch 1 taken 78 times.
✓ Branch 2 taken 482 times.
✗ Branch 3 not taken.
560 if (testType >= 4 && testType <= 7) {
234
1/2
✓ Branch 0 taken 482 times.
✗ Branch 1 not taken.
482 drawFadePattern(channelData, percentOfCycle, testType);
235 482 return;
236 }
237 unsigned char clr[3];
238
3/3
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
78 switch (cycleNum % 3) {
239 73 case 0:
240 73 clr[0] = clr[2] = 0;
241 73 clr[1] = 255;
242 73 break;
243 3 case 1:
244 3 clr[2] = clr[1] = 0;
245 3 clr[0] = 255;
246 3 break;
247 2 default:
248 2 clr[0] = clr[1] = 0;
249 2 clr[2] = 255;
250 2 break;
251 }
252
253 78 int actualHeight = height;
254 78 int actualWidth = width;
255
256
2/4
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
78 if ((orientation == 'L') || (orientation == 'R')) {
257 ✗ actualHeight = width;
258 ✗ actualWidth = height;
259 }
260
261
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 78 times.
702 for (int y = 0; y < (actualHeight / 2); y++) {
262 624 int yw1 = y * actualWidth * 3;
263 624 int yw2 = (y + (actualHeight / 2)) * actualWidth * 3;
264
265
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 624 times.
20592 for (int x = 0; x < actualWidth; ++x) {
266 19968 int r = 0, g = 0, b = 0;
267 19968 int r2 = 0, g2 = 0, b2 = 0;
268 // Left Column
269
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 19344 times.
19968 if (x == 0) {
270 624 r = r2 = clr[0];
271 624 g = g2 = clr[1];
272 624 b = b2 = clr[2];
273 }
274 // Right Column
275
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 19344 times.
19968 if (x == (actualWidth - 1)) {
276 624 r = r2 = clr[1];
277 624 g = g2 = clr[2];
278 624 b = b2 = clr[0];
279 }
280 // Top Row (for yw1)
281
2/2
✓ Branch 0 taken 2496 times.
✓ Branch 1 taken 17472 times.
19968 if (y == 0) {
282 2496 r = clr[2];
283 2496 g = clr[0];
284 2496 b = clr[1];
285 }
286 // Bottom Row (for yw2)
287
2/2
✓ Branch 0 taken 2496 times.
✓ Branch 1 taken 17472 times.
19968 if (y == (actualHeight / 2 - 1)) {
288 2496 r2 = clr[2];
289 2496 g2 = clr[0];
290 2496 b2 = clr[1];
291 }
292 // Diagonal Top-Left to Middle
293
4/4
✓ Branch 0 taken 19344 times.
✓ Branch 1 taken 624 times.
✓ Branch 2 taken 624 times.
✓ Branch 3 taken 18720 times.
19968 if (x == (2 * y) || x == (2 * y + 1)) {
294 1248 r = g = 255;
295 }
296 // Diagonal Bottom-Left to Middle (part1)
297
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 19344 times.
19968 if (x == (2 * (actualHeight / 2 - 1 - y))) {
298 624 b2 = g2 = 255;
299 }
300 // Diagonal Bottom-Left to Middle (part2)
301
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 19344 times.
19968 if (x == (2 * (actualHeight / 2 - 1 - y) + 1)) {
302 624 b2 = g2 = 255;
303 }
304 // Square in middle
305
4/4
✓ Branch 0 taken 11232 times.
✓ Branch 1 taken 8736 times.
✓ Branch 2 taken 2496 times.
✓ Branch 3 taken 8736 times.
19968 if (x >= (actualWidth / 2 - 2) && x <= (actualWidth / 2 + 1)) {
306
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 1872 times.
2496 if (y <= 1) {
307 624 r2 = g2 = b2 = 255;
308
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 1248 times.
1872 } else if (y >= (actualHeight / 2 - 2)) {
309 624 r = g = b = 255;
310 }
311 }
312
313
1/2
✓ Branch 0 taken 19968 times.
✗ Branch 1 not taken.
19968 setPixel(channelData, yw1 + x * 3, r, g, b);
314
1/2
✓ Branch 0 taken 19968 times.
✗ Branch 1 not taken.
19968 setPixel(channelData, yw2 + x * 3, r2, g2, b2);
315 }
316 }
317
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
✓ Branch 2 taken 78 times.
✗ Branch 3 not taken.
78 drawNumber(output + 1, width / 2 + 1, height > 16 ? 2 : 1, channelData);
318
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
✓ Branch 2 taken 78 times.
✗ Branch 3 not taken.
78 drawNumber(chain + 1, width / 2 + 8, height > 16 ? 2 : 1, channelData);
319 }
320
321 // Write r,g,b to the pixel's own channels so the output applies the color order
322 286720 void LEDPanel::setPixel(unsigned char* channelData, int idx, int r, int g, int b) {
323 286720 int base = std::min(pixelMap[idx], std::min(pixelMap[idx + 1], pixelMap[idx + 2]));
324 286720 channelData[base] = r;
325 286720 channelData[base + 1] = g;
326 286720 channelData[base + 2] = b;
327 286720 }
328
329 482 void LEDPanel::drawFadePattern(unsigned char* channelData, float percentOfCycle, int testType) {
330 // Same triangle fade the pixel-string testers use (PixelFadeStringTester).
331 uint8_t fade;
332
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 200 times.
482 if (percentOfCycle < 0.50f) {
333 282 fade = percentOfCycle * 508.0f + 1;
334 } else {
335 200 fade = 255 - (percentOfCycle - 0.5f) * 508.0f;
336 }
337 // 4 = red, 5 = green, 6 = blue, 7 = white.
338
4/4
✓ Branch 0 taken 351 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 250 times.
482 uint8_t r = (testType == 4 || testType == 7) ? fade : 0;
339
4/4
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 256 times.
482 uint8_t g = (testType == 5 || testType == 7) ? fade : 0;
340
4/4
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 256 times.
482 uint8_t b = (testType == 6 || testType == 7) ? fade : 0;
341
342 482 int actualHeight = height;
343 482 int actualWidth = width;
344
2/4
✓ Branch 0 taken 482 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 482 times.
482 if ((orientation == 'L') || (orientation == 'R')) {
345 ✗ actualHeight = width;
346 ✗ actualWidth = height;
347 }
348
2/2
✓ Branch 0 taken 7712 times.
✓ Branch 1 taken 482 times.
8194 for (int y = 0; y < actualHeight; y++) {
349 7712 int yw = y * actualWidth * 3;
350
2/2
✓ Branch 0 taken 246784 times.
✓ Branch 1 taken 7712 times.
254496 for (int x = 0; x < actualWidth; ++x) {
351 246784 setPixel(channelData, yw + x * 3, r, g, b);
352 }
353 }
354 482 }
355
356 156 void LEDPanel::drawNumber(int v, int x, int y, unsigned char* channelData) {
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 if (v >= 20) {
358 ✗ drawNumber(2, x, y, channelData);
359 ✗ x += 4;
360 ✗ v -= 20;
361 }
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 if (v >= 10) {
363 ✗ drawNumber(1, x, y, channelData);
364 ✗ x += 2;
365 ✗ v -= 10;
366 }
367
368 int yw1;
369 156 int actualWidth = width;
370
371
2/4
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 156 times.
156 if ((orientation == 'L') || (orientation == 'R')) {
372 ✗ actualWidth = height;
373 }
374
375
1/2
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
156 if (v == 1) {
376
2/2
✓ Branch 0 taken 780 times.
✓ Branch 1 taken 156 times.
936 for (int yo = 0; yo < 5; yo++) {
377 780 int yw1 = (y + yo) * actualWidth * 3;
378 780 channelData[pixelMap[yw1 + x * 3]] = 255;
379 780 channelData[pixelMap[yw1 + x * 3 + 1]] = 255;
380 780 channelData[pixelMap[yw1 + x * 3 + 2]] = 255;
381 }
382 156 return;
383 }
384 ✗ if (v == 4) {
385 ✗ for (int yo = 0; yo < 5; yo++) {
386 ✗ int yw1 = (y + yo) * actualWidth * 3;
387 ✗ channelData[pixelMap[yw1 + (x + 2) * 3]] = 255;
388 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 1]] = 255;
389 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 2]] = 255;
390 ✗ if (yo < 3) {
391 ✗ channelData[pixelMap[yw1 + x * 3]] = 255;
392 ✗ channelData[pixelMap[yw1 + x * 3 + 1]] = 255;
393 ✗ channelData[pixelMap[yw1 + x * 3 + 2]] = 255;
394 }
395 }
396 ✗ yw1 = (y + 2) * actualWidth * 3;
397 ✗ for (int x2 = 0; x2 < 3; x2++) {
398 ✗ channelData[pixelMap[yw1 + (x + x2) * 3]] = 255;
399 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 1]] = 255;
400 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 2]] = 255;
401 }
402 ✗ return;
403 }
404 ✗ if (v == 7) {
405 ✗ for (int yo = 0; yo < 5; yo++) {
406 ✗ int yw1 = (y + yo) * actualWidth * 3;
407 ✗ channelData[pixelMap[yw1 + (x + 2) * 3]] = 255;
408 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 1]] = 255;
409 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 2]] = 255;
410 }
411 ✗ yw1 = y * actualWidth * 3;
412 ✗ for (int x2 = 0; x2 < 3; x2++) {
413 ✗ channelData[pixelMap[yw1 + (x + x2) * 3]] = 255;
414 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 1]] = 255;
415 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 2]] = 255;
416 }
417 ✗ return;
418 }
419 ✗ yw1 = y * actualWidth * 3;
420 ✗ for (int x2 = 0; x2 < 3; x2++) {
421 ✗ channelData[pixelMap[yw1 + (x + x2) * 3]] = 255;
422 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 1]] = 255;
423 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 2]] = 255;
424
425 ✗ if (x2 != 1 || v != 0) {
426 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + actualWidth * 6]] = 255;
427 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 1 + actualWidth * 6]] = 255;
428 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 2 + actualWidth * 6]] = 255;
429 }
430
431 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + actualWidth * 12]] = 255;
432 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 1 + actualWidth * 12]] = 255;
433 ✗ channelData[pixelMap[yw1 + (x + x2) * 3 + 2 + actualWidth * 12]] = 255;
434 }
435 ✗ yw1 = (y + 1) * actualWidth * 3;
436 ✗ if (v == 5 || v == 6 || v == 9 || v == 8 || v == 0) {
437 ✗ channelData[pixelMap[yw1 + x * 3]] = 255;
438 ✗ channelData[pixelMap[yw1 + x * 3 + 1]] = 255;
439 ✗ channelData[pixelMap[yw1 + x * 3 + 2]] = 255;
440 }
441 ✗ if (v == 2 || v == 3 || v == 9 || v == 8 || v == 0) {
442 ✗ channelData[pixelMap[yw1 + (x + 2) * 3]] = 255;
443 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 1]] = 255;
444 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 2]] = 255;
445 }
446 ✗ yw1 = (y + 3) * actualWidth * 3;
447 ✗ if (v == 2 || v == 6 || v == 8 || v == 0) {
448 ✗ channelData[pixelMap[yw1 + x * 3]] = 255;
449 ✗ channelData[pixelMap[yw1 + x * 3 + 1]] = 255;
450 ✗ channelData[pixelMap[yw1 + x * 3 + 2]] = 255;
451 }
452 ✗ if (v == 3 || v == 5 || v == 6 || v == 8 | v == 9 || v == 0) {
453 ✗ channelData[pixelMap[yw1 + (x + 2) * 3]] = 255;
454 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 1]] = 255;
455 ✗ channelData[pixelMap[yw1 + (x + 2) * 3 + 2]] = 255;
456 }
457 }
458