FastLED 3.10.6
Loading...
Searching...
No Matches
builder.cpp.hpp
Go to the documentation of this file.
1// ok no header - implementation file for fl::fled::FledBuilder
2// declared in fl/fled/builder.h. Hand-builds a v1 .fled byte buffer
3// from header bytes + optional JSON sections + payload, then routes
4// through Fled::loadFromVector for the canonical parse path.
5
6#include "fl/fled/builder.h"
7
8#include "fl/fled/color.h"
9#include "fl/fled/fled.h"
10#include "fl/stl/int.h"
11#include "fl/stl/move.h"
12#include "fl/stl/noexcept.h"
13#include "fl/stl/string.h"
14#include "fl/stl/vector.h"
15
16namespace fl {
17namespace fled {
18
19namespace {
20
21// Append a u32 little-endian to a byte vector.
23 out.push_back(static_cast<fl::u8>(v & 0xff));
24 out.push_back(static_cast<fl::u8>((v >> 8) & 0xff));
25 out.push_back(static_cast<fl::u8>((v >> 16) & 0xff));
26 out.push_back(static_cast<fl::u8>((v >> 24) & 0xff));
27}
28
29// Append the characters of a fl::string to a byte vector.
31 const fl::size n = s.size();
32 for (fl::size i = 0; i < n; ++i) {
33 out.push_back(static_cast<fl::u8>(s[i]));
34 }
35}
36
37// Build the JSON envelope by concatenating the configured sections under
38// their canonical top-level keys. If no sections are configured the
39// envelope is "{}".
40fl::string buildEnvelope(const fl::string& screenMapJson,
41 const fl::string& channelsJson,
42 const fl::string& videoColorJson) FL_NO_EXCEPT {
43 fl::string out;
44 out += '{';
45 bool first = true;
46 if (!screenMapJson.empty()) {
47 out += "\"map\":";
48 out += screenMapJson;
49 first = false;
50 }
51 if (!channelsJson.empty()) {
52 if (!first) out += ',';
53 out += "\"channels\":";
54 out += channelsJson;
55 first = false;
56 }
57 if (!videoColorJson.empty()) {
58 if (!first) out += ',';
59 out += "\"video\":{\"color\":";
60 out += videoColorJson;
61 out += '}';
62 first = false;
63 }
64 out += '}';
65 return out;
66}
67
68// Spellings are the ones FLED_FORMAT.md defines. They are written here rather
69// than derived from the enum so that renaming a C++ enumerator cannot silently
70// change the wire format.
72 switch (p) {
73 case ColorPrimaries::Bt709: return "bt709";
74 case ColorPrimaries::DisplayP3: return "display-p3";
75 case ColorPrimaries::Bt2020: return "bt2020";
76 case ColorPrimaries::Custom: return nullptr; // emitted as an object
77 }
78 return "bt709";
79}
80
82 switch (t) {
83 case ColorTransfer::Srgb: return "srgb";
84 case ColorTransfer::Bt709: return "bt709";
85 case ColorTransfer::Linear: return "linear";
86 }
87 return "srgb";
88}
89
90// A CIE xy pair, four decimals -- enough for the D65 white point (0.3127,
91// 0.3290) to survive the round trip exactly.
92void appendXy(fl::string& out, float x, float y) FL_NO_EXCEPT {
93 out += '[';
94 out += fl::to_string(x, 4);
95 out += ',';
96 out += fl::to_string(y, 4);
97 out += ']';
98}
99
101 fl::string out;
102 out += "{\"primaries\":";
103 const char* named = primariesName(c.primaries);
104 if (named != nullptr) {
105 out += '"';
106 out += named;
107 out += '"';
108 } else {
109 out += "{\"red\":";
110 appendXy(out, c.customPrimaries[0], c.customPrimaries[1]);
111 out += ",\"green\":";
112 appendXy(out, c.customPrimaries[2], c.customPrimaries[3]);
113 out += ",\"blue\":";
114 appendXy(out, c.customPrimaries[4], c.customPrimaries[5]);
115 out += ",\"white\":";
116 appendXy(out, c.customPrimaries[6], c.customPrimaries[7]);
117 out += '}';
118 }
119 out += ",\"transfer\":\"";
120 out += transferName(c.transfer);
121 // v1 defines exactly one value for each of matrix and range; the parser
122 // rejects anything else, so emitting them literally keeps producer and
123 // parser from drifting apart.
124 out += "\",\"matrix\":\"rgb\",\"range\":\"full\"}";
125 return out;
126}
127
128} // namespace
129
137
139 mVersion = v;
140 return *this;
141}
142
147
149 mScreenMapJson = (json != nullptr) ? fl::string(json) : fl::string();
150 return *this;
151}
152
154 mChannelsJson = (json != nullptr) ? fl::string(json) : fl::string();
155 return *this;
156}
157
159 mVideoColorJson = serializeVideoColor(color);
160 return *this;
161}
162
164 mPayload.assign(bytes.begin(), bytes.end());
165 return *this;
166}
167
169 const fl::string envelope =
171 const fl::u32 jsonLen = static_cast<fl::u32>(envelope.size());
172
174 buf.reserve(12 + envelope.size() + mPayload.size());
175
176 // 12-byte header: 4-byte magic, version, pixel_format, 2 reserved,
177 // u32 little-endian JSON length.
178 buf.push_back('F');
179 buf.push_back('L');
180 buf.push_back('E');
181 buf.push_back('D');
182 buf.push_back(mVersion);
184 buf.push_back(0); // reserved
185 buf.push_back(0); // reserved
186 appendU32LE(buf, jsonLen);
187
188 // JSON envelope.
189 appendString(buf, envelope);
190
191 // Optional frame payload (already a copy held by the builder).
192 for (fl::size i = 0; i < mPayload.size(); ++i) {
193 buf.push_back(mPayload[i]);
194 }
195
197}
198
199} // namespace fled
200} // namespace fl
static Fled loadFromVector(fl::vector< fl::u8 > &&bytes) FL_NO_EXCEPT
Definition fled.cpp.hpp:59
fl::size size() const FL_NO_EXCEPT
fl::string mScreenMapJson
Definition builder.h:67
FledBuilder & setPixelFormat(fl::u8 fmt) FL_NO_EXCEPT
FledBuilder() FL_NO_EXCEPT
FledBuilder & setVideoColor(const VideoColor &color) FL_NO_EXCEPT
FledBuilder & setChannelsJson(const char *json) FL_NO_EXCEPT
fl::string mVideoColorJson
Definition builder.h:69
fl::vector< fl::u8 > mPayload
Definition builder.h:70
fl::Fled build() const FL_NO_EXCEPT
fl::string mChannelsJson
Definition builder.h:68
FledBuilder & setVersion(fl::u8 v) FL_NO_EXCEPT
FledBuilder & setPayload(fl::span< const fl::u8 > bytes) FL_NO_EXCEPT
FledBuilder & setScreenMapJson(const char *json) FL_NO_EXCEPT
void reserve(fl::size n) FL_NO_EXCEPT
Definition vector.h:591
void push_back(const T &value) FL_NO_EXCEPT
Definition vector.h:624
fl::string buildEnvelope(const fl::string &screenMapJson, const fl::string &channelsJson, const fl::string &videoColorJson) FL_NO_EXCEPT
void appendString(fl::vector< fl::u8 > &out, const fl::string &s) FL_NO_EXCEPT
fl::string serializeVideoColor(const VideoColor &c) FL_NO_EXCEPT
void appendU32LE(fl::vector< fl::u8 > &out, fl::u32 v) FL_NO_EXCEPT
const char * primariesName(ColorPrimaries p) FL_NO_EXCEPT
void appendXy(fl::string &out, float x, float y) FL_NO_EXCEPT
const char * transferName(ColorTransfer t) FL_NO_EXCEPT
ColorPrimaries
Definition color.h:25
ColorTransfer
Definition color.h:34
unsigned char u8
Definition stdint.h:131
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:28
InputGamut g FL_NO_EXCEPT
Definition rgbw.h:121
string to_string(T value) FL_NO_EXCEPT
Definition string.h:459
Base definition for an LED controller.
Definition crgb.hpp:179