| 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 "../log.h" | ||
| 16 | |||
| 17 | #include "../Sequence.h" | ||
| 18 | #include "Matrix.h" | ||
| 19 | #include <cstring> // memcpy -- needed directly for NOPCH builds | ||
| 20 | |||
| 21 | /* | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | 118 | Matrix::Matrix(int startChannel, int width, int height) : | |
| 25 | 118 | m_startChannel(startChannel), | |
| 26 | 118 | m_width(width), | |
| 27 | 118 | m_height(height) { | |
| 28 |
1/2✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
|
118 | LogDebug(VB_CHANNELOUT, "New Matrix: %dx%d\n", width, height); |
| 29 | |||
| 30 |
1/2✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
|
118 | m_buffer = new unsigned char[width * height * 3]; |
| 31 | |||
| 32 | 118 | m_enableFlagOffset = startChannel + (width * height * 3); | |
| 33 | 118 | } | |
| 34 | |||
| 35 | /* | ||
| 36 | * | ||
| 37 | */ | ||
| 38 | 118 | Matrix::~Matrix() { | |
| 39 |
1/2✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
|
118 | delete[] m_buffer; |
| 40 | 118 | } | |
| 41 | |||
| 42 | /* | ||
| 43 | * | ||
| 44 | */ | ||
| 45 | 4 | void Matrix::AddSubMatrix(int enabled, int startChannel, int width, int height, | |
| 46 | int xOffset, int yOffset) { | ||
| 47 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | LogDebug(VB_CHANNELOUT, |
| 48 | "New SubMatrix: %dx%d+%d+%d @ channel %d, enabled: %d\n", | ||
| 49 | width, height, xOffset, yOffset, startChannel, enabled); | ||
| 50 | // Every frame copies the sub-matrix into m_buffer row by row, from its | ||
| 51 | // own channels: one that does not fit inside the matrix overran the heap | ||
| 52 | // buffer, and channels outside the channel data read past it. | ||
| 53 |
5/8✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
|
4 | if (width <= 0 || height <= 0 || xOffset < 0 || yOffset < 0 || |
| 54 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
3 | (int64_t)xOffset + width > m_width || (int64_t)yOffset + height > m_height || |
| 55 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | startChannel < 0 || (int64_t)startChannel + (int64_t)width * height * 3 > FPPD_MAX_CHANNELS) { |
| 56 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | LogErr(VB_CHANNELOUT, "Ignoring sub-matrix %dx%d+%d+%d at channel %d: it does not fit the %dx%d matrix or the channel data\n", |
| 57 | width, height, xOffset, yOffset, startChannel + 1, m_width, m_height); | ||
| 58 | 3 | return; | |
| 59 | } | ||
| 60 | SubMatrix newSub; | ||
| 61 | |||
| 62 | 1 | newSub.enabled = enabled; | |
| 63 | 1 | newSub.startChannel = startChannel; | |
| 64 | 1 | newSub.width = width; | |
| 65 | 1 | newSub.height = height; | |
| 66 | 1 | newSub.xOffset = xOffset; | |
| 67 | 1 | newSub.yOffset = yOffset; | |
| 68 | |||
| 69 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | subMatrix.push_back(newSub); |
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * | ||
| 74 | */ | ||
| 75 | 9 | void Matrix::OverlaySubMatrix(unsigned char* channelData, int i) { | |
| 76 |
3/6✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
|
9 | if (i < 0 || i >= (int)subMatrix.size()) |
| 77 | ✗ | return; | |
| 78 | |||
| 79 | // Check to see if this submatrix is enabled. The enable flags follow the | ||
| 80 | // matrix's own channels, so a matrix that ends at the top of the channel | ||
| 81 | // data has none. | ||
| 82 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
|
9 | if (!subMatrix[i].enabled && |
| 83 | ✗ | ((int64_t)m_enableFlagOffset + i >= FPPD_MAX_CHANNELS || !channelData[m_enableFlagOffset + i])) | |
| 84 | ✗ | return; | |
| 85 | |||
| 86 | 9 | int startChannel = subMatrix[i].startChannel; | |
| 87 | 9 | int xOffset = subMatrix[i].xOffset; | |
| 88 | 9 | int yOffset = subMatrix[i].yOffset; | |
| 89 | |||
| 90 | unsigned char* src; | ||
| 91 | unsigned char* dest; | ||
| 92 | |||
| 93 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
|
18 | for (int y = 0; y < subMatrix[i].height; y++) { |
| 94 | 9 | src = channelData + subMatrix[i].startChannel + (y * subMatrix[i].width * 3); | |
| 95 | 9 | dest = m_buffer + ((y + subMatrix[i].yOffset) * m_width * 3) + (subMatrix[i].xOffset * 3); | |
| 96 | |||
| 97 | 9 | memcpy(dest, src, subMatrix[i].width * 3); | |
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /* | ||
| 102 | * | ||
| 103 | */ | ||
| 104 | 3253 | void Matrix::OverlaySubMatrices(unsigned char* channelData) { | |
| 105 |
2/2✓ Branch 0 taken 3244 times.
✓ Branch 1 taken 9 times.
|
3253 | if (!subMatrix.size()) |
| 106 | 3244 | return; | |
| 107 | |||
| 108 | // Clear the matrix before applying submatrices | ||
| 109 | // bzero(m_buffer, m_width * m_height * 3); | ||
| 110 | |||
| 111 | // Instead, just populate our temp buffer with the contents of the matrix | ||
| 112 | 9 | memcpy(m_buffer, channelData + m_startChannel, m_width * m_height * 3); | |
| 113 | |||
| 114 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
|
18 | for (int i = 0; i < subMatrix.size(); i++) { |
| 115 | 9 | OverlaySubMatrix(channelData, i); | |
| 116 | } | ||
| 117 | |||
| 118 | 9 | memcpy(channelData + m_startChannel, m_buffer, m_width * m_height * 3); | |
| 119 | } | ||
| 120 |