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