FastLED 3.10.6
Loading...
Searching...
No Matches
color.h
Go to the documentation of this file.
1#pragma once
2
3// Source color metadata for the .fled v1 container - the `video.color`
4// envelope block. See FLED_FORMAT.md "Source Color Metadata" for the
5// canonical contract (the authority is the ledmapper spec that file mirrors).
6//
7// This layer CARRIES and VALIDATES the declaration, and toSourceProfile()
8// turns a resolved one into the SourceProfile a colour-managed channel
9// decodes with (#4460). Binding it is the sketch's choice: legacy playback,
10// with no profile bound, ignores it and stays byte-identical.
11
12#include "fl/stl/int.h"
13#include "fl/stl/noexcept.h"
15
16namespace fl {
17
18class json;
19struct SourceProfile;
20
21namespace fled {
22
23// Chromaticities + white point of the source. Custom carries explicit CIE xy
24// pairs in VideoColor::customPrimaries.
25enum class ColorPrimaries : fl::u8 {
26 Bt709 = 0, // BT.709 / sRGB primaries, D65 white
30};
31
32// Transfer function. `Srgb` is the piecewise sRGB function, NOT the BT.709
33// camera OETF - the spec keeps them distinct on purpose.
34enum class ColorTransfer : fl::u8 {
35 Srgb = 0,
38};
39
40// Component encoding. v1 defines only the identity (direct RGB) case;
41// YCbCr coefficient sets are reserved for a pixel format that can carry them.
42enum class ColorMatrix : fl::u8 {
43 Rgb = 0,
44};
45
46// Code range. v1 defines only full range; `limited` is reserved.
47enum class ColorRange : fl::u8 {
48 Full = 0,
49};
50
51// Outcome of resolving `video.color` against the header's pixel_format.
52// Every non-Ok value is a rejection: FLED_FORMAT.md requires a clear
53// diagnostic rather than a silent fallback.
54enum class ColorStatus : fl::u8 {
55 Ok = 0,
56 // Caller passed a null out-pointer. API misuse, not a bad file - kept
57 // distinct so a diagnostic never sends someone hunting a valid envelope.
59 // `video.color` absent on a pixel format that defines no default tuple
60 // (gray8, rgbw8). Not malformed - just undeclared, and unresolvable.
62 // `video.color` present but not a JSON object.
68 // Rules 2/3: display-encoded formats reject linear/pq/hlg;
69 // rgb16_linear rejects anything but linear.
71 // Rule 4: `range: "limited"` is reserved in v1.
73 // Rule 5: any matrix other than `rgb` is reserved in v1.
75 // Rule 6: gray8/rgbw8 must declare all four keys or none.
77 // Rule 7: custom primaries object missing a key or with a malformed pair.
79};
80
81// A resolved source-color declaration. `declared` distinguishes "the file
82// said so" from "the default tuple was applied", which matters because the
83// default is a compatibility interpretation, not an author's statement.
84struct VideoColor {
90 // Valid only when primaries == Custom. Layout:
91 // {red.x, red.y, green.x, green.y, blue.x, blue.y, white.x, white.y}
93};
94
95// True if `pixelFormat` defines a default color tuple (the display-encoded
96// RGB family and rgb16_linear). gray8 and rgbw8 do not: gray8 carries no
97// chromaticity and rgbw8's white is a device primary RGB cannot describe.
99
100// The default tuple for a pixel format, per FLED_FORMAT.md. Returns false
101// (leaving *out untouched) for formats that define none.
102bool defaultVideoColor(fl::u8 pixelFormat, VideoColor* out) FL_NO_EXCEPT;
103
104// Resolve `envelope["video"]["color"]` against the header's pixel_format,
105// applying the default tuple for absent keys where the format defines one
106// and enforcing every validation rule in FLED_FORMAT.md.
107//
108// On ColorStatus::Ok, *out holds the resolved tuple. On any other status
109// *out is left untouched and the status names the rejection reason.
110ColorStatus resolveVideoColor(const fl::json& envelope, fl::u8 pixelFormat,
112
113// Typed overload. Kept in the public API because callers hold a PixelFormat
114// and should not have to cast to the wire byte to resolve a color tuple.
115ColorStatus resolveVideoColor(const fl::json& envelope, PixelFormat pixelFormat,
117
118// Stable human-readable text for a status, for diagnostics. Never null.
120
121// The colour-pipeline source profile a resolved declaration describes: its
122// primaries (named, or the custom xy pairs) and its transfer function. Bind
123// it to decode a file colour-accurately on a colour-managed channel, e.g.
124// FastLED.setDefaultSourceProfile(profile);
125// or ChannelOptions::setColorProfile(emitter, profile). Returns false only
126// for a null out-pointer; every resolvable VideoColor has a SourceProfile.
128
129} // namespace fled
130} // namespace fl
bool defaultVideoColor(fl::u8 pixelFormat, VideoColor *out) FL_NO_EXCEPT
ColorStatus resolveVideoColor(const fl::json &envelope, fl::u8 pixelFormat, VideoColor *out) FL_NO_EXCEPT
bool toSourceProfile(const VideoColor &color, SourceProfile *out) FL_NO_EXCEPT
ColorStatus
Definition color.h:54
@ TransferConflictsWithFormat
Definition color.h:70
bool pixelFormatHasDefaultTuple(fl::u8 pixelFormat) FL_NO_EXCEPT
ColorPrimaries
Definition color.h:25
ColorTransfer
Definition color.h:34
ColorMatrix
Definition color.h:42
ColorRange
Definition color.h:47
const char * colorStatusMessage(ColorStatus status) FL_NO_EXCEPT
ColorMatrix matrix
Definition color.h:87
ColorPrimaries primaries
Definition color.h:85
ColorRange range
Definition color.h:88
ColorTransfer transfer
Definition color.h:86
float customPrimaries[8]
Definition color.h:92
unsigned char u8
Definition stdint.h:131
InputGamut g FL_NO_EXCEPT
Definition rgbw.h:121
Base definition for an LED controller.
Definition crgb.hpp:179
A source declaration, not a container or an output-device selection.