GCC Code Coverage Report


Directory: ./
File: channeloutput/processors/FoldOutputProcessor.cpp
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 46 66 69.7%
Functions: 3 5 60.0%
Branches: 39 84 46.4%

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 "fpp-json.h"
16
17 #include "../../Warnings.h"
18 #include "../../log.h"
19
20 #include "FoldOutputProcessor.h"
21
22 7 FoldOutputProcessor::FoldOutputProcessor(const Json::Value& config) {
23
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 description = config["description"].asString();
24
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 active = config["active"].asInt() ? true : false;
25
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 sourceChannel = config["source"].asInt() - 1;
26
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 count = config["count"].asInt();
27
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 node = config["node"].asInt(); // By channel, RGB Pixel, RGBW Pixel
28
29 // node is the UI selector, nodesize the channels per node it selects. All of
30 // the fold index math below is in nodesize, never in the raw selector.
31
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (node == 1) {
32 3 nodesize = 3;
33
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (node == 2) {
34 ✗ nodesize = 4;
35 } else {
36
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (node != 0) {
37 1 std::string warning = "Fold output processor has an unknown node option (" +
38
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 std::to_string(node) + "), falling back to By Channel";
39
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 LogWarn(VB_CHANNELOUT, "%s\n", warning.c_str());
40
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 WarningHolder::AddWarning(warning);
41 1 node = 0;
42 1 }
43 4 nodesize = 1;
44 }
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (count < 0) {
46 ✗ std::string warning = "Fold output processor has a negative channel count (" +
47 ✗ std::to_string(count) + "), disabling it";
48 ✗ LogWarn(VB_CHANNELOUT, "%s\n", warning.c_str());
49 ✗ WarningHolder::AddWarning(warning);
50 ✗ count = 0;
51 ✗ }
52 // "source" is the 1-based channel the UI shows, so anything below 1 puts
53 // sourceChannel before the start of the buffer ProcessData indexes.
54
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 if (sourceChannel < 0) {
55 4 std::string warning = "Fold output processor has an invalid start channel (" +
56
4/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
8 std::to_string(config["source"].asInt()) + "), disabling it";
57
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 LogWarn(VB_CHANNELOUT, "%s\n", warning.c_str());
58
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 WarningHolder::AddWarning(warning);
59 4 sourceChannel = 0;
60 4 count = 0;
61 4 }
62 // sourceChannel + count is reported in an int: keep both where it can't
63 // overflow into the inverted, "nothing to do" range rangeIsValid() passes.
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (sourceChannel > (int)FPPD_MAX_CHANNELS) {
65 ✗ sourceChannel = FPPD_MAX_CHANNELS;
66 }
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (count > (int)FPPD_MAX_CHANNELS + 1) {
68 ✗ count = FPPD_MAX_CHANNELS + 1;
69 }
70
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 LogInfo(VB_CHANNELOUT, "Fold: channels: %d-%d, node size: %d\n",
71 sourceChannel, sourceChannel + count, nodesize);
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (count % nodesize != 0) {
73 ✗ LogWarn(VB_CHANNELOUT,
74 "Channel count (%d) is not a multiple of the node size "
75 "(%d channels/node), the dangling channels will be ignored\n",
76 count, nodesize);
77 }
78
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 tempBuffer.resize(count);
79 7 }
80
81 ✗ FoldOutputProcessor::FoldOutputProcessor(int src, int c, int n) {
82 ✗ active = true;
83 ✗ sourceChannel = src;
84 ✗ count = c < 0 ? 0 : c;
85 ✗ nodesize = n > 0 ? n : 1;
86 ✗ node = nodesize == 4 ? 2 : (nodesize == 3 ? 1 : 0);
87 ✗ tempBuffer.resize(count);
88 ✗ }
89
90 ✗ FoldOutputProcessor::~FoldOutputProcessor() {
91 ✗ }
92 14 void FoldOutputProcessor::GetRequiredChannelRanges(const std::function<void(int, int)>& addRange) {
93 14 addRange(sourceChannel, sourceChannel + count);
94 14 }
95
96 115 void FoldOutputProcessor::ProcessData(unsigned char* channelData) const {
97 115 size_t len = count / nodesize; // Number of whole nodes; trailing channels are left alone
98
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 59 times.
115 if (len == 0) {
99 56 return;
100 }
101 // The fold reads every source node and writes it elsewhere in the same span,
102 // so the pre-fold values have to be snapshotted first.
103 59 memcpy(tempBuffer.data(), channelData + sourceChannel, count);
104
2/2
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 59 times.
1199 for (unsigned int node = 0; node < len; ++node) {
105 2280 memcpy(
106 2280 channelData + sourceChannel +
107
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
1140 (node % 2 ? len - node / 2 - 1 : node / 2) * nodesize,
108
2/2
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 570 times.
1140 tempBuffer.data() + node * nodesize,
109 1140 nodesize);
110 }
111 }
112