GCC Code Coverage Report


Directory: ./
File: channeloutput/processors/BrightnessOutputProcessor.cpp
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 36 38 94.7%
Functions: 3 3 100.0%
Branches: 66 104 63.5%

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 #include "../../overlays/PixelOverlay.h"
15 #include "../../overlays/PixelOverlayModel.h"
16
17 #include <math.h>
18 #include <stdio.h>
19
20 #include "fpp-json.h"
21
22 #include "../../Warnings.h"
23 #include "../../log.h"
24
25 #include "BrightnessOutputProcessor.h"
26 #include "OutputProcessor.h"
27
28 53 BrightnessOutputProcessor::BrightnessOutputProcessor(const Json::Value& config) {
29
2/4
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
53 description = config["description"].asString();
30
2/4
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
53 active = config["active"].asInt() ? true : false;
31
3/4
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 1 times.
53 start = config["start"].asInt();
32
2/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 count = config["count"].asInt();
33
2/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 brightness = config["brightness"].asInt();
34
3/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 1 times.
52 gamma = config["gamma"].asFloat();
35
36 // A blank UI field arrives as JSON null and a config predating the field
37 // has no key at all; both read back as 0 -- and pow(x, 0) is 1, so an
38 // unvalidated zero gamma builds a table that drives EVERY input, including
39 // dark channels, at the full brightness value.
40
9/12
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 48 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 48 times.
51 if (!config.isMember("brightness") || config["brightness"].isNull()) {
41
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 WarningHolder::AddWarning("Brightness output processor '" + description + "' has no brightness value, using 100");
42 3 brightness = 100;
43
4/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 46 times.
48 } else if (brightness < 0 || brightness > 100) {
44
5/10
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
2 WarningHolder::AddWarning("Brightness output processor '" + description + "' has an invalid brightness (" + std::to_string(brightness) + "), clamping");
45
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 brightness = brightness < 0 ? 0 : 100;
46 }
47
9/12
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 48 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 48 times.
51 if (!config.isMember("gamma") || config["gamma"].isNull()) {
48
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 WarningHolder::AddWarning("Brightness output processor '" + description + "' has no gamma value, using 1.0");
49 3 gamma = 1.0f;
50
3/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47 times.
48 } else if (gamma < 0.01f || gamma > 50.0f) {
51
6/12
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 WarningHolder::AddWarning("Brightness output processor '" + description + "' has an invalid gamma (" + std::to_string(gamma) + "), using 1.0");
52 1 gamma = 1.0f;
53 }
54
55
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 ProcessModelConfig(config, model, start, count);
56
57
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 LogInfo(VB_CHANNELOUT, "Brightness: %d-%d => Brightness:%d Gamma: %f Model: %s\n",
58 start + 1, start + count,
59 brightness, gamma, model.c_str());
60
61 51 float bf = brightness;
62 51 float maxB = bf * 2.55f;
63
2/2
✓ Branch 0 taken 13056 times.
✓ Branch 1 taken 51 times.
13107 for (int x = 0; x < 256; x++) {
64 13056 float f = x;
65 13056 f = maxB * pow(f / 255.0f, gamma);
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13056 times.
13056 if (f > 255.0) {
67 ✗ f = 255.0;
68 }
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13056 times.
13056 if (f < 0.0) {
70 ✗ f = 0.0;
71 }
72 13056 table[x] = round(f);
73 }
74 55 }
75
76 160 BrightnessOutputProcessor::~BrightnessOutputProcessor() {
77 160 }
78
79 287 void BrightnessOutputProcessor::ProcessData(unsigned char* channelData) const {
80
2/2
✓ Branch 0 taken 24420 times.
✓ Branch 1 taken 287 times.
24707 for (int x = 0; x < count; x++) {
81 24420 channelData[start + x] = table[channelData[start + x]];
82 }
83 287 }
84