1 /*
2  * This file is part of libplacebo.
3  *
4  * libplacebo is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * libplacebo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with libplacebo.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LIBPLACEBO_COLORSPACE_H_
19 #define LIBPLACEBO_COLORSPACE_H_
20 
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 
25 #include <libplacebo/common.h>
26 
27 PL_API_BEGIN
28 
29 // The underlying color representation (e.g. RGB, XYZ or YCbCr)
30 enum pl_color_system {
31     PL_COLOR_SYSTEM_UNKNOWN = 0,
32     // YCbCr-like color systems:
33     PL_COLOR_SYSTEM_BT_601,      // ITU-R Rec. BT.601 (SD)
34     PL_COLOR_SYSTEM_BT_709,      // ITU-R Rec. BT.709 (HD)
35     PL_COLOR_SYSTEM_SMPTE_240M,  // SMPTE-240M
36     PL_COLOR_SYSTEM_BT_2020_NC,  // ITU-R Rec. BT.2020 (non-constant luminance)
37     PL_COLOR_SYSTEM_BT_2020_C,   // ITU-R Rec. BT.2020 (constant luminance)
38     PL_COLOR_SYSTEM_BT_2100_PQ,  // ITU-R Rec. BT.2100 ICtCp PQ variant
39     PL_COLOR_SYSTEM_BT_2100_HLG, // ITU-R Rec. BT.2100 ICtCp HLG variant
40     PL_COLOR_SYSTEM_YCGCO,       // YCgCo (derived from RGB)
41     // Other color systems:
42     PL_COLOR_SYSTEM_RGB,         // Red, Green and Blue
43     PL_COLOR_SYSTEM_XYZ,         // CIE 1931 XYZ, pre-encoded with gamma 2.6
44     PL_COLOR_SYSTEM_COUNT
45 };
46 
47 bool pl_color_system_is_ycbcr_like(enum pl_color_system sys);
48 
49 // Returns true for color systems that are linear transformations of the RGB
50 // equivalent, i.e. are simple matrix multiplications. For color systems with
51 // this property, `pl_color_repr_decode` is sufficient for conversion to RGB.
52 bool pl_color_system_is_linear(enum pl_color_system sys);
53 
54 // Guesses the best YCbCr-like colorspace based on a image given resolution.
55 // This only picks conservative values. (In particular, BT.2020 is never
56 // auto-guessed, even for 4K resolution content)
57 enum pl_color_system pl_color_system_guess_ycbcr(int width, int height);
58 
59 // Friendly names for the canonical channel names and order.
60 enum pl_channel {
61     PL_CHANNEL_NONE = -1,
62     PL_CHANNEL_A = 3, // alpha
63     // RGB system
64     PL_CHANNEL_R = 0,
65     PL_CHANNEL_G = 1,
66     PL_CHANNEL_B = 2,
67     // YCbCr-like systems
68     PL_CHANNEL_Y = 0,
69     PL_CHANNEL_CB = 1,
70     PL_CHANNEL_CR = 2,
71     // Aliases for Cb/Cr
72     PL_CHANNEL_U = 1,
73     PL_CHANNEL_V = 2
74     // There are deliberately no names for the XYZ system to avoid
75     // confusion due to PL_CHANNEL_Y.
76 };
77 
78 // The numerical range of the representation (where applicable).
79 enum pl_color_levels {
80     PL_COLOR_LEVELS_UNKNOWN = 0,
81     PL_COLOR_LEVELS_LIMITED,    // Limited/TV range, e.g. 16-235
82     PL_COLOR_LEVELS_FULL,       // Full/PC range, e.g. 0-255
83     PL_COLOR_LEVELS_COUNT,
84 
85     // Compatibility aliases
86     PL_COLOR_LEVELS_TV = PL_COLOR_LEVELS_LIMITED,
87     PL_COLOR_LEVELS_PC = PL_COLOR_LEVELS_FULL,
88 };
89 
90 // The alpha representation mode.
91 enum pl_alpha_mode {
92     PL_ALPHA_UNKNOWN = 0,   // or no alpha channel present
93     PL_ALPHA_INDEPENDENT,   // alpha channel is separate from the video
94     PL_ALPHA_PREMULTIPLIED, // alpha channel is multiplied into the colors
95     PL_ALPHA_MODE_COUNT,
96 };
97 
98 // The underlying bit-wise representation of a color sample. For example,
99 // a 10-bit TV-range YCbCr value uploaded to a 16 bit texture would have
100 // sample_depth=16 color_depth=10 bit_shift=0.
101 //
102 // For another example, a 12-bit XYZ full range sample shifted to 16-bits with
103 // the lower 4 bits all set to 0 would have sample_depth=16 color_depth=12
104 // bit_shift=4. (libavcodec likes outputting this type of `xyz12`)
105 //
106 // To explain the meaning of `sample_depth` further; the consideration factor
107 // here is the fact that GPU sampling will normalized the sampled color to the
108 // range 0.0 - 1.0 in a manner dependent on the number of bits in the texture
109 // format. So if you upload a 10-bit YCbCr value unpadded as 16-bit color
110 // samples, all of the sampled values will be extremely close to 0.0. In such a
111 // case, `pl_color_repr_normalize` would return a high scaling factor, which
112 // would pull the color up to their 16-bit range.
113 struct pl_bit_encoding {
114     int sample_depth; // the number of bits the color is stored/sampled as
115     int color_depth;  // the effective number of bits of the color information
116     int bit_shift;    // a representational bit shift applied to the color
117 };
118 
119 // Returns whether two bit encodings are exactly identical.
120 bool pl_bit_encoding_equal(const struct pl_bit_encoding *b1,
121                            const struct pl_bit_encoding *b2);
122 
123 // Struct describing the underlying color system and representation. This
124 // information is needed to convert an encoded color to a normalized RGB triple
125 // in the range 0-1.
126 struct pl_color_repr {
127     enum pl_color_system sys;
128     enum pl_color_levels levels;
129     enum pl_alpha_mode alpha;
130     struct pl_bit_encoding bits; // or {0} if unknown
131 };
132 
133 // Some common color representations. It's worth pointing out that all of these
134 // presets leave `alpha` and `bits` as unknown - that is, only the system and
135 // levels are predefined
136 extern const struct pl_color_repr pl_color_repr_unknown;
137 extern const struct pl_color_repr pl_color_repr_rgb;
138 extern const struct pl_color_repr pl_color_repr_sdtv;
139 extern const struct pl_color_repr pl_color_repr_hdtv;  // also Blu-ray
140 extern const struct pl_color_repr pl_color_repr_uhdtv; // SDR, NCL system
141 extern const struct pl_color_repr pl_color_repr_jpeg;
142 
143 // Returns whether two colorspace representations are exactly identical.
144 bool pl_color_repr_equal(const struct pl_color_repr *c1,
145                          const struct pl_color_repr *c2);
146 
147 // Replaces unknown values in the first struct by those of the second struct.
148 void pl_color_repr_merge(struct pl_color_repr *orig,
149                          const struct pl_color_repr *update);
150 
151 // This function normalizes the color representation such that
152 // color_depth=sample_depth and bit_shift=0; and returns the scaling factor
153 // that must be multiplied into the color value to accomplish this, assuming
154 // it has already been sampled by the GPU. If unknown, the color and sample
155 // depth will both be inferred as 8 bits for the purposes of this conversion.
156 float pl_color_repr_normalize(struct pl_color_repr *repr);
157 
158 // Guesses the best color levels based on the specified color levels and
159 // falling back to using the color system instead. YCbCr-like systems are
160 // assumed to be TV range, otherwise this defaults to PC range.
161 enum pl_color_levels pl_color_levels_guess(const struct pl_color_repr *repr);
162 
163 // The colorspace's primaries (gamut)
164 enum pl_color_primaries {
165     PL_COLOR_PRIM_UNKNOWN = 0,
166     // Standard gamut:
167     PL_COLOR_PRIM_BT_601_525,   // ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)
168     PL_COLOR_PRIM_BT_601_625,   // ITU-R Rec. BT.601 (625-line = PAL, SECAM)
169     PL_COLOR_PRIM_BT_709,       // ITU-R Rec. BT.709 (HD), also sRGB
170     PL_COLOR_PRIM_BT_470M,      // ITU-R Rec. BT.470 M
171     PL_COLOR_PRIM_EBU_3213,     // EBU Tech. 3213-E / JEDEC P22 phosphors
172     // Wide gamut:
173     PL_COLOR_PRIM_BT_2020,      // ITU-R Rec. BT.2020 (UltraHD)
174     PL_COLOR_PRIM_APPLE,        // Apple RGB
175     PL_COLOR_PRIM_ADOBE,        // Adobe RGB (1998)
176     PL_COLOR_PRIM_PRO_PHOTO,    // ProPhoto RGB (ROMM)
177     PL_COLOR_PRIM_CIE_1931,     // CIE 1931 RGB primaries
178     PL_COLOR_PRIM_DCI_P3,       // DCI-P3 (Digital Cinema)
179     PL_COLOR_PRIM_DISPLAY_P3,   // DCI-P3 (Digital Cinema) with D65 white point
180     PL_COLOR_PRIM_V_GAMUT,      // Panasonic V-Gamut (VARICAM)
181     PL_COLOR_PRIM_S_GAMUT,      // Sony S-Gamut
182     PL_COLOR_PRIM_FILM_C,       // Traditional film primaries with Illuminant C
183     PL_COLOR_PRIM_COUNT
184 };
185 
186 bool pl_color_primaries_is_wide_gamut(enum pl_color_primaries prim);
187 
188 // Guesses the best primaries based on a resolution. This always guesses
189 // conservatively, i.e. it will never return a wide gamut color space even if
190 // the resolution is 4K.
191 enum pl_color_primaries pl_color_primaries_guess(int width, int height);
192 
193 // The colorspace's transfer function (gamma / EOTF)
194 enum pl_color_transfer {
195     PL_COLOR_TRC_UNKNOWN = 0,
196     // Standard dynamic range:
197     PL_COLOR_TRC_BT_1886,       // ITU-R Rec. BT.1886 (CRT emulation + OOTF)
198     PL_COLOR_TRC_SRGB,          // IEC 61966-2-4 sRGB (CRT emulation)
199     PL_COLOR_TRC_LINEAR,        // Linear light content
200     PL_COLOR_TRC_GAMMA18,       // Pure power gamma 1.8
201     PL_COLOR_TRC_GAMMA20,       // Pure power gamma 2.0
202     PL_COLOR_TRC_GAMMA22,       // Pure power gamma 2.2
203     PL_COLOR_TRC_GAMMA24,       // Pure power gamma 2.4
204     PL_COLOR_TRC_GAMMA26,       // Pure power gamma 2.6
205     PL_COLOR_TRC_GAMMA28,       // Pure power gamma 2.8
206     PL_COLOR_TRC_PRO_PHOTO,     // ProPhoto RGB (ROMM)
207     // High dynamic range:
208     PL_COLOR_TRC_PQ,            // ITU-R BT.2100 PQ (perceptual quantizer), aka SMPTE ST2048
209     PL_COLOR_TRC_HLG,           // ITU-R BT.2100 HLG (hybrid log-gamma), aka ARIB STD-B67
210     PL_COLOR_TRC_V_LOG,         // Panasonic V-Log (VARICAM)
211     PL_COLOR_TRC_S_LOG1,        // Sony S-Log1
212     PL_COLOR_TRC_S_LOG2,        // Sony S-Log2
213     PL_COLOR_TRC_COUNT
214 };
215 
216 // Returns the nominal peak of a given transfer function, relative to the
217 // reference white. This refers to the highest encodable signal level.
218 // Always equal to 1.0 for SDR curves.
219 //
220 // Note: This returns the highest encodable signal by definition of the EOTF,
221 // regardless of the ultimate representation (e.g. scene or display referred).
222 // For HLG in particular, this is always around 3.77 - which is potentially
223 // different from the signal peak after applying the OOTF to go from scene
224 // referred to display referred (resulting in a display-referred peak of around
225 // 4.92 for a 1000 cd/m^2 HLG reference display).
226 float pl_color_transfer_nominal_peak(enum pl_color_transfer trc);
227 
pl_color_transfer_is_hdr(enum pl_color_transfer trc)228 static inline bool pl_color_transfer_is_hdr(enum pl_color_transfer trc)
229 {
230     return pl_color_transfer_nominal_peak(trc) > 1.0;
231 }
232 
233 // This defines the display-space standard reference white level (in cd/m^2)
234 // that is assumed for SDR content, for use when mapping between HDR and SDR in
235 // display space. See ITU-R Report BT.2408 for more information.
236 #define PL_COLOR_SDR_WHITE 203.0
237 
238 // For HLG, which is scene-referred and dependent on the peak luminance of the
239 // display device, rather than targeting a fixed cd/m^2 level in display space,
240 // we target the 75% level in scene space. This maps to the same brightness
241 // level in display space when viewed under the OOTF of a 1000 cd/m^2 HLG
242 // reference display.
243 #define PL_COLOR_SDR_WHITE_HLG 3.17955
244 
245 // Compatibility alias for older versions of libplacebo
246 #define PL_COLOR_REF_WHITE PL_COLOR_SDR_WHITE
247 
248 // The semantic interpretation of the decoded image, how is it mastered?
249 enum pl_color_light {
250     PL_COLOR_LIGHT_UNKNOWN = 0,
251     PL_COLOR_LIGHT_DISPLAY,     // Display-referred, output as-is
252     PL_COLOR_LIGHT_SCENE_HLG,   // Scene-referred, HLG OOTF
253     PL_COLOR_LIGHT_SCENE_709_1886, // Scene-referred, OOTF = BT.709+1886 interaction
254     PL_COLOR_LIGHT_SCENE_1_2,   // Scene-referred, OOTF = gamma 1.2
255     PL_COLOR_LIGHT_COUNT
256 };
257 
258 bool pl_color_light_is_scene_referred(enum pl_color_light light);
259 
260 // Rendering intent for colorspace transformations. These constants match the
261 // ICC specification (Table 23)
262 enum pl_rendering_intent {
263     PL_INTENT_PERCEPTUAL = 0,
264     PL_INTENT_RELATIVE_COLORIMETRIC = 1,
265     PL_INTENT_SATURATION = 2,
266     PL_INTENT_ABSOLUTE_COLORIMETRIC = 3
267 };
268 
269 // Struct describing a physical color space. This information is needed to
270 // turn a normalized RGB triple into its physical meaning, as well as to convert
271 // between color spaces.
272 struct pl_color_space {
273     enum pl_color_primaries primaries;
274     enum pl_color_transfer transfer;
275     enum pl_color_light light;
276 
277     // The highest value that occurs in the signal, relative to the reference
278     // white, alternatively the brightest color value supported by a given
279     // color space. (0 = unknown)
280     float sig_peak;
281 
282     // The average light level that occurs in the signal, relative to the
283     // reference white, alternatively the desired average brightness level of a
284     // given color space. (0 = unknown)
285     float sig_avg;
286 
287     // The signal floor, i.e. black point, relative to the reference white.
288     // This effectively determines the signal's contrast, as well. Note that
289     // for most SDR curves, this can only be 0.0 and will effectively be
290     // ignored if otherwise. It only applies to absolute luminance transfer
291     // functions (such as PQ or S-Log), as well as BT.1886.
292     //
293     // Note that a value of 0.0 exactly is treated effectively as "unknown",
294     // and will be defaulted to a contrast of 1000:1 for BT.1886. To override
295     // this logic (thus turning BT.1886 into a true gamma 2.4 function), either
296     // set the transfer function explicitly to PL_COLOR_TRC_GAMMA24, or set
297     // this value to something sufficiently low like FLT_EPSILON. (Never mind
298     // that such high contrast values are unrealistic anyway)
299     float sig_floor;
300 
301     // Additional scale factor for the signal's reference white. If this is set
302     // to a value higher than 1.0, then it's assumed that the signal's encoded
303     // reference white is assumed to be brighter than normal by this factor.
304     // This can be used to over- or under-expose content, especially HDR
305     // content. (0 = unknown)
306     //
307     // An example of where this could come in use is for using an SDR transfer
308     // function (e.g. PL_COLOR_TRC_LINEAR) to encode a HDR image or display.
309     float sig_scale;
310 };
311 
312 // Returns whether or not a color space is considered as effectively HDR.
313 // This is true when the effective signal peak is greater than the SDR
314 // reference white (1.0), after application of the `sig_scale`.
315 bool pl_color_space_is_hdr(struct pl_color_space csp);
316 
317 // Returns whether or not a color space is "black scaled", in which case 0.0 is
318 // the true black point. This is true for SDR signals other than BT.1886, as
319 // well as for HLG.
320 bool pl_color_space_is_black_scaled(struct pl_color_space csp);
321 
322 // Replaces unknown values in the first struct by those of the second struct.
323 void pl_color_space_merge(struct pl_color_space *orig,
324                           const struct pl_color_space *update);
325 
326 // Returns whether two colorspaces are exactly identical.
327 bool pl_color_space_equal(const struct pl_color_space *c1,
328                           const struct pl_color_space *c2);
329 
330 // Go through a color-space and explicitly default all unknown fields to
331 // reasonable values. After this function is called, none of the values will be
332 // PL_COLOR_*_UNKNOWN or 0.0.
333 void pl_color_space_infer(struct pl_color_space *space);
334 
335 // Like `pl_color_space_infer`, but takes default values from the reference
336 // color space (excluding certain special cases like HDR or wide gamut). This
337 // is basically the logic used by `pl_shader_color_map` to decide the output
338 // color space in a conservative way.
339 void pl_color_space_infer_ref(struct pl_color_space *space,
340                               const struct pl_color_space *ref);
341 
342 // Some common color spaces. Note: These don't necessarily have all fields
343 // filled, in particular `sig_peak` and `sig_avg` are left unset.
344 extern const struct pl_color_space pl_color_space_unknown;
345 extern const struct pl_color_space pl_color_space_srgb;
346 extern const struct pl_color_space pl_color_space_bt709;
347 extern const struct pl_color_space pl_color_space_hdr10;
348 extern const struct pl_color_space pl_color_space_bt2020_hlg;
349 extern const struct pl_color_space pl_color_space_monitor; // typical display
350 
351 // This represents metadata about extra operations to perform during colorspace
352 // conversion, which correspond to artistic adjustments of the color.
353 struct pl_color_adjustment {
354     // Brightness boost. 0.0 = neutral, 1.0 = solid white, -1.0 = solid black
355     float brightness;
356     // Contrast boost. 1.0 = neutral, 0.0 = solid black
357     float contrast;
358     // Saturation gain. 1.0 = neutral, 0.0 = grayscale
359     float saturation;
360     // Hue shift, corresponding to a rotation around the [U, V] subvector, in
361     // radians. Only meaningful for YCbCr-like colorspaces. 0.0 = neutral
362     float hue;
363     // Gamma adjustment. 1.0 = neutral, 0.0 = solid black
364     float gamma;
365     // Color temperature shift. 0.0 = 6500 K, -1.0 = 3000 K, 1.0 = 10000 K
366     float temperature;
367 };
368 
369 // A struct pre-filled with all-neutral values.
370 extern const struct pl_color_adjustment pl_color_adjustment_neutral;
371 
372 // Represents the chroma placement with respect to the luma samples. This is
373 // only relevant for YCbCr-like colorspaces with chroma subsampling.
374 enum pl_chroma_location {
375     PL_CHROMA_UNKNOWN = 0,
376     PL_CHROMA_LEFT,             // MPEG2/4, H.264
377     PL_CHROMA_CENTER,           // MPEG1, JPEG
378     PL_CHROMA_TOP_LEFT,
379     PL_CHROMA_TOP_CENTER,
380     PL_CHROMA_BOTTOM_LEFT,
381     PL_CHROMA_BOTTOM_CENTER,
382     PL_CHROMA_COUNT,
383 };
384 
385 // Fills *x and *y with the offset in luma pixels corresponding to a given
386 // chroma location.
387 //
388 // Note: PL_CHROMA_UNKNOWN defaults to PL_CHROMA_LEFT
389 void pl_chroma_location_offset(enum pl_chroma_location loc, float *x, float *y);
390 
391 // Represents a single CIE xy coordinate (e.g. CIE Yxy with Y = 1.0)
392 struct pl_cie_xy {
393     float x, y;
394 };
395 
396 // Recovers (X / Y) from a CIE xy value.
pl_cie_X(struct pl_cie_xy xy)397 static inline float pl_cie_X(struct pl_cie_xy xy) {
398     return xy.x / xy.y;
399 }
400 
401 // Recovers (Z / Y) from a CIE xy value.
pl_cie_Z(struct pl_cie_xy xy)402 static inline float pl_cie_Z(struct pl_cie_xy xy) {
403     return (1 - xy.x - xy.y) / xy.y;
404 }
405 
pl_cie_xy_equal(const struct pl_cie_xy * a,const struct pl_cie_xy * b)406 static inline float pl_cie_xy_equal(const struct pl_cie_xy *a,
407                                     const struct pl_cie_xy *b)
408 {
409     return a->x == b->x && a->y == b->y;
410 }
411 
412 // Computes the CIE xy chromaticity coordinates of a CIE D-series illuminant
413 // with the given correlated color temperature.
414 //
415 // `temperature` must be between 2500 K and 25000 K, inclusive.
416 struct pl_cie_xy pl_white_from_temp(float temperature);
417 
418 // Represents the raw physical primaries corresponding to a color space.
419 struct pl_raw_primaries {
420     struct pl_cie_xy red, green, blue, white;
421 };
422 
423 // Returns whether two raw primaries are exactly identical.
424 bool pl_raw_primaries_equal(const struct pl_raw_primaries *a,
425                             const struct pl_raw_primaries *b);
426 
427 // Returns the raw primaries for a given color space.
428 const struct pl_raw_primaries *pl_raw_primaries_get(enum pl_color_primaries prim);
429 
430 // Returns an RGB->XYZ conversion matrix for a given set of primaries.
431 // Multiplying this into the RGB color transforms it to CIE XYZ, centered
432 // around the color space's white point.
433 struct pl_matrix3x3 pl_get_rgb2xyz_matrix(const struct pl_raw_primaries *prim);
434 
435 // Similar to pl_get_rgb2xyz_matrix, but gives the inverse transformation.
436 struct pl_matrix3x3 pl_get_xyz2rgb_matrix(const struct pl_raw_primaries *prim);
437 
438 // Returns a primary adaptation matrix, which converts from one set of
439 // primaries to another. This is an RGB->RGB transformation. For rendering
440 // intents other than PL_INTENT_ABSOLUTE_COLORIMETRIC, the white point is
441 // adapted using the Bradford matrix.
442 struct pl_matrix3x3 pl_get_color_mapping_matrix(const struct pl_raw_primaries *src,
443                                                 const struct pl_raw_primaries *dst,
444                                                 enum pl_rendering_intent intent);
445 
446 // Return a chromatic adaptation matrix, which converts from one white point to
447 // another, using the Bradford matrix. This is an RGB->RGB transformation.
448 struct pl_matrix3x3 pl_get_adaptation_matrix(struct pl_cie_xy src, struct pl_cie_xy dst);
449 
450 // Returns true if 'b' is entirely contained in 'a'. Useful for figuring out if
451 // colorimetric clipping will occur or not.
452 bool pl_primaries_superset(const struct pl_raw_primaries *a,
453                            const struct pl_raw_primaries *b);
454 
455 // Cone types involved in human vision
456 enum pl_cone {
457     PL_CONE_L = 1 << 0,
458     PL_CONE_M = 1 << 1,
459     PL_CONE_S = 1 << 2,
460 
461     // Convenience aliases
462     PL_CONE_NONE = 0,
463     PL_CONE_LM   = PL_CONE_L | PL_CONE_M,
464     PL_CONE_MS   = PL_CONE_M | PL_CONE_S,
465     PL_CONE_LS   = PL_CONE_L | PL_CONE_S,
466     PL_CONE_LMS  = PL_CONE_L | PL_CONE_M | PL_CONE_S,
467 };
468 
469 // Structure describing parameters for simulating color blindness
470 struct pl_cone_params {
471     enum pl_cone cones; // Which cones are *affected* by the vision model
472     float strength;     // Coefficient for how strong the defect is
473                         // (1.0 = Unaffected, 0.0 = Full blindness)
474 };
475 
476 // Built-in color blindness models
477 extern const struct pl_cone_params pl_vision_normal;        // No distortion (92%)
478 extern const struct pl_cone_params pl_vision_protanomaly;   // Red deficiency (0.66%)
479 extern const struct pl_cone_params pl_vision_protanopia;    // Red absence (0.59%)
480 extern const struct pl_cone_params pl_vision_deuteranomaly; // Green deficiency (2.7%)
481 extern const struct pl_cone_params pl_vision_deuteranopia;  // Green absence (0.56%)
482 extern const struct pl_cone_params pl_vision_tritanomaly;   // Blue deficiency (0.01%)
483 extern const struct pl_cone_params pl_vision_tritanopia;    // Blue absence (0.016%)
484 extern const struct pl_cone_params pl_vision_monochromacy;  // Blue cones only (<0.001%)
485 extern const struct pl_cone_params pl_vision_achromatopsia; // Rods only (<0.0001%)
486 
487 // Returns a cone adaptation matrix. Applying this to an RGB color in the given
488 // color space will apply the given cone adaptation coefficients for simulating
489 // a type of color blindness.
490 //
491 // For the color blindness models which don't entail complete loss of a cone,
492 // you can partially counteract the effect by using a similar model with the
493 // `strength` set to its inverse. For example, to partially counteract
494 // deuteranomaly, you could generate a cone matrix for PL_CONE_M with the
495 // strength 2.0 (or some other number above 1.0).
496 struct pl_matrix3x3 pl_get_cone_matrix(const struct pl_cone_params *params,
497                                        const struct pl_raw_primaries *prim);
498 
499 // Returns a color decoding matrix for a given combination of source color
500 // representation and adjustment parameters. This mutates `repr` to reflect the
501 // change. If `params` is NULL, it defaults to &pl_color_adjustment_neutral.
502 //
503 // This function always performs a conversion to RGB. To convert to other
504 // colorspaces (e.g. between YUV systems), obtain a second YUV->RGB matrix
505 // and invert it using `pl_transform3x3_invert`.
506 //
507 // Note: For BT.2020 constant-luminance, this outputs chroma information in the
508 // range [-0.5, 0.5]. Since the CL system conversion is non-linear, further
509 // processing must be done by the caller. The channel order is CrYCb.
510 //
511 // Note: For BT.2100 ICtCp, this outputs in the color space L'M'S'. Further
512 // non-linear processing must be done by the caller.
513 //
514 // Note: For XYZ system, the input/encoding gamma must be pre-applied by the
515 // user, typically this has a value of 2.6.
516 struct pl_transform3x3 pl_color_repr_decode(struct pl_color_repr *repr,
517                                     const struct pl_color_adjustment *params);
518 
519 // Common struct to describe an ICC profile
520 struct pl_icc_profile {
521     // Points to the in-memory representation of the ICC profile. This is
522     // allowed to be NULL, in which case the `pl_icc_profile` represents "no
523     // profile”.
524     const void *data;
525     size_t len;
526 
527     // If a profile is set, this signature must uniquely identify it. It could
528     // be, for example, a checksum of the profile contents. Alternatively, it
529     // could be the pointer to the ICC profile itself, as long as the user
530     // makes sure that this memory is used in an immutable way. For a third
531     // possible interpretation, consider simply incrementing this uint64_t
532     // every time you suspect the profile has changed.
533     uint64_t signature;
534 };
535 
536 // This doesn't do a comparison of the actual contents, only of the signature.
537 bool pl_icc_profile_equal(const struct pl_icc_profile *p1,
538                           const struct pl_icc_profile *p2);
539 
540 // Sets `signature` to a hash of `profile->data`, if non-NULL. Provided as a
541 // convenience function for the sake of users ingesting arbitrary ICC profiles
542 // from sources where they can't reliably detect profile changes.
543 void pl_icc_profile_compute_signature(struct pl_icc_profile *profile);
544 
545 PL_API_END
546 
547 #endif // LIBPLACEBO_COLORSPACE_H_
548