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_SHADERS_COLORSPACE_H_
19 #define LIBPLACEBO_SHADERS_COLORSPACE_H_
20 
21 // Color space transformation shaders. These all input and output a color
22 // value (PL_SHADER_SIG_COLOR).
23 
24 #include <libplacebo/colorspace.h>
25 #include <libplacebo/shaders.h>
26 
27 PL_API_BEGIN
28 
29 // Decode the color into normalized RGB, given a specified color_repr. This
30 // also takes care of additional pre- and post-conversions requires for the
31 // "special" color systems (XYZ, BT.2020-C, etc.). If `params` is left as NULL,
32 // it defaults to &pl_color_adjustment_neutral.
33 //
34 // Note: This function always returns PC-range RGB with pre-multiplied alpha.
35 // It mutates the pl_color_repr to reflect the change.
36 void pl_shader_decode_color(pl_shader sh, struct pl_color_repr *repr,
37                             const struct pl_color_adjustment *params);
38 
39 // Encodes a color from normalized, PC-range, pre-multiplied RGB into a given
40 // representation. That is, this performs the inverse operation of
41 // `pl_shader_decode_color` (sans color adjustments).
42 void pl_shader_encode_color(pl_shader sh, const struct pl_color_repr *repr);
43 
44 // Linearize (expand) `vec4 color`, given a specified color space. In essence,
45 // this corresponds to the ITU-R EOTF.
46 //
47 // Note: Unlike the ITU-R EOTF, it never includes the OOTF - even for systems
48 // where the EOTF includes the OOTF (such as HLG).
49 void pl_shader_linearize(pl_shader sh, struct pl_color_space csp);
50 
51 // Delinearize (compress), given a color space as output. This loosely
52 // corresponds to the inverse EOTF (not the OETF) in ITU-R terminology, again
53 // assuming a reference monitor.
54 void pl_shader_delinearize(pl_shader sh, struct pl_color_space csp);
55 
56 struct pl_sigmoid_params {
57     // The center (bias) of the sigmoid curve. Must be between 0.0 and 1.0.
58     // If left as NULL, defaults to 0.75
59     float center;
60 
61     // The slope (steepness) of the sigmoid curve. Must be between 1.0 and 20.0.
62     // If left as NULL, defaults to 6.5.
63     float slope;
64 };
65 
66 extern const struct pl_sigmoid_params pl_sigmoid_default_params;
67 
68 // Applies a sigmoidal color transform to all channels. This helps avoid
69 // ringing artifacts during upscaling by bringing the color information closer
70 // to neutral and away from the extremes. If `params` is NULL, it defaults to
71 // &pl_sigmoid_default_params.
72 //
73 // Warning: This function clamps the input to the interval [0,1]; and as such
74 // it should *NOT* be used on already-decoded high-dynamic range content.
75 void pl_shader_sigmoidize(pl_shader sh, const struct pl_sigmoid_params *params);
76 
77 // This performs the inverse operation to `pl_shader_sigmoidize`.
78 void pl_shader_unsigmoidize(pl_shader sh, const struct pl_sigmoid_params *params);
79 
80 struct pl_peak_detect_params {
81     // Smoothing coefficient for the detected values. This controls the time
82     // parameter (tau) of an IIR low pass filter. In other words, it represent
83     // the cutoff period (= 1 / cutoff frequency) in frames. Frequencies below
84     // this length will be suppressed. This helps block out annoying
85     // "sparkling" or "flickering" due to small variations in frame-to-frame
86     // brightness.
87     //
88     // If left unset, this defaults to 100.0.
89     float smoothing_period;
90 
91     // In order to avoid reacting sluggishly on scene changes as a result of
92     // the low-pass filter, we disable it when the difference between the
93     // current frame brightness and the average frame brightness exceeds a
94     // given threshold difference. But rather than a single hard cutoff, which
95     // would lead to weird discontinuities on fades, we gradually disable it
96     // over a small window of brightness ranges. These parameters control the
97     // lower and upper bounds of this window, in dB.
98     //
99     // The default values are 5.5 and 10.0, respectively. To disable this logic
100     // entirely, set either one to a negative value.
101     float scene_threshold_low;
102     float scene_threshold_high;
103 
104     // In order to avoid clipping on fade-ins or other sudden brightness
105     // increases, we always over-estimate the peak brightness (in percent)
106     // by this amount, as a percentage of the actual measured peak. If left
107     // as 0.0, this logic is disabled. The default value is 0.05.
108     float overshoot_margin;
109 
110     // To avoid over-tone-mapping very dark scenes (or black frames), this
111     // imposes a hard lower bound on the detected peak. If left as 0.0, it
112     // instead defaults to a value of 1.0.
113     float minimum_peak;
114 };
115 
116 extern const struct pl_peak_detect_params pl_peak_detect_default_params;
117 
118 // This function can be used to measure the `sig_peak` and `sig_avg` of a
119 // video source automatically, using a compute shader. The measured values
120 // are smoothed automatically (depending on the parameters), so to keep track
121 // of the measured results over time, a shader object is used to hold the state.
122 // Returns false on failure initializing the peak detection object, or if
123 // compute shaders are not supported.
124 //
125 // It's important that the same shader object is used for successive frames
126 // belonging to the same source. If the source changes (e.g. due to a file
127 // change or seek), the user should not re-use the same state object.
128 //
129 // The parameter `csp` holds the representation of the color values that are
130 // the input to this function. (They must already be in decoded RGB form, i.e.
131 // alternate color representations are not supported)
132 bool pl_shader_detect_peak(pl_shader sh, struct pl_color_space csp,
133                            pl_shader_obj *state,
134                            const struct pl_peak_detect_params *params);
135 
136 // After dispatching the above shader, this function *may* be used to read out
137 // the detected `sig_peak` and `sig_avg` directly. If the shader has never been
138 // dispatched yet, i.e. no information is available, this will return false.
139 //
140 // Note: This function will block until the shader object is no longer in use
141 // by the GPU, so its use should be avoided due to performance reasons. This
142 // function is *not* needed when the user only wants to use `pl_shader_color_map`,
143 // since that can ingest the peak detection state object directly. It only
144 // serves as a utility/debugging function.
145 bool pl_get_detected_peak(const pl_shader_obj state,
146                           float *out_peak, float *out_avg);
147 
148 // A collection of various tone mapping algorithms supported by libplacebo.
149 enum pl_tone_mapping_algorithm {
150     // Performs no tone-mapping, just clips out-of-gamut colors. Retains perfect
151     // color accuracy for in-gamut colors but completely destroys out-of-gamut
152     // information.
153     PL_TONE_MAPPING_CLIP,
154 
155     // Generalization of the reinhard tone mapping algorithm to support an
156     // additional linear slope near black. The tone mapping parameter indicates
157     // the trade-off between the linear section and the non-linear section.
158     // Essentially, for param=0.5, every color value below 0.5 will be mapped
159     // linearly, with the higher values being non-linearly tone mapped. Values
160     // near 1.0 make this curve behave like CLIP, and values near 0.0 make this
161     // curve behave like REINHARD. The default value is 0.3, which provides a
162     // good balance between colorimetric accuracy and preserving out-of-gamut
163     // details. The name is derived from its function shape (ax+b)/(cx+d), which
164     // is known as a Möbius transformation in mathematics.
165     //
166     // This is the recommended tone mapping function to use when stretching an
167     // SDR curve over an HDR display (i.e. `dst.sig_scale > 1.0`), which can
168     // come in handy when calibrating a true HDR display to an SDR curve
169     // for compatibility with legacy display stacks.
170     PL_TONE_MAPPING_MOBIUS,
171 
172     // Simple non-linear, global tone mapping algorithm. Named after Erik
173     // Reinhard. The parameter specifies the local contrast coefficient at the
174     // display peak. Essentially, a value of param=0.5 implies that the
175     // reference white will be about half as bright as when clipping. Defaults
176     // to 0.5, which results in the simplest formulation of this function.
177     PL_TONE_MAPPING_REINHARD,
178 
179     // Piece-wise, filmic tone-mapping algorithm developed by John Hable for
180     // use in Uncharted 2, inspired by a similar tone-mapping algorithm used by
181     // Kodak. Popularized by its use in video games with HDR rendering.
182     // Preserves both dark and bright details very well, but comes with the
183     // drawback of darkening the overall image quite significantly. Users are
184     // recommended to use HDR peak detection to compensate for the missing
185     // brightness. This is sort of similar to REINHARD tone-mapping + parameter
186     // 0.24.
187     PL_TONE_MAPPING_HABLE,
188 
189     // Fits a gamma (power) function to transfer between the source and target
190     // color spaces. This preserves details at all scales fairly accurately,
191     // but can result in an image with a muted or dull appearance. Best when
192     // combined with peak detection. The parameter is used as the exponent of
193     // the gamma function, defaulting to 1.8.
194     PL_TONE_MAPPING_GAMMA,
195 
196     // Linearly stretches the source gamut to the destination gamut. This will
197     // preserve all details accurately, but results in a significantly darker
198     // image. Best when combined with peak detection. The parameter can be used
199     // as an additional scaling coefficient to make the image (linearly)
200     // brighter or darker. Defaults to 1.0.
201     PL_TONE_MAPPING_LINEAR,
202 
203     // EETF from the ITU-R Report BT.2390, a hermite spline roll-off with
204     // linear segment. Not configurable.
205     PL_TONE_MAPPING_BT_2390,
206 
207     PL_TONE_MAPPING_ALGORITHM_COUNT,
208 };
209 
210 struct pl_color_map_params {
211     // The rendering intent to use for RGB->RGB primary conversions.
212     // Defaults to PL_INTENT_RELATIVE_COLORIMETRIC.
213     enum pl_rendering_intent intent;
214 
215     // Algorithm and configuration used for tone-mapping. For non-tunable
216     // algorithms, the `param` is ignored. If the tone mapping parameter is
217     // left as 0.0, the tone-mapping curve's preferred default parameter will
218     // be used. The default algorithm is PL_TONE_MAPPING_BT_2390.
219     enum pl_tone_mapping_algorithm tone_mapping_algo;
220     float tone_mapping_param;
221 
222     // The tone mapping algorithm can operate in two modes: The first is known
223     // as "desaturating" (per-channel) mode, aka "hollywood/TV" style tone
224     // mapping; and the second is called "saturating" (linear) mode, aka
225     // "chromatic/colorimetric" tone mapping. The saturating tone mapping
226     // algorithm preserves colors from the source faithfully, but can suffer
227     // from weird-looking, blown out highlights in very bright regions. To
228     // provide a trade-off between these two approaches, we mix the result
229     // between the two approaches based on the overall brightness of the pixel.
230     //
231     // These settings control the parameter of this mixing. The `strength`
232     // controls how much of the desaturating result is mixed into the pixel,
233     // with values ranging from 0.0 to 1.0 - while the `base` and `exponent`
234     // controls the placement and steepness of the mixing curve.
235     //
236     // If you want to always use the saturating/colorimetric tone mapping, set
237     // the strength to 0.0. If you want to always use the desaturating/hollywood
238     // tone mapping, set the strength to 1.0 and the exponent to 0.0. The
239     // default settings are strength 0.90, exponent 0.2 and base 0.18, which
240     // provide a fairly strong preset while nonetheless preserving some amount
241     // of colorimetric accuracy.
242     float desaturation_strength;
243     float desaturation_exponent;
244     float desaturation_base;
245 
246     // When tone mapping, this represents the upper limit of how much the
247     // scene may be over-exposed in order to hit the `dst.sig_avg` target.
248     // If left unset, defaults to 1.0, which corresponds to no boost.
249     float max_boost;
250 
251     // If true, enables the gamut warning feature. This will visibly highlight
252     // all out-of-gamut colors (by coloring them pink), if they would have been
253     // clipped as a result of gamut or tone mapping.
254     bool gamut_warning;
255 
256     // If true, enables colorimetric clipping. This will colorimetrically clip
257     // out-of-gamut colors by desaturating them until they hit the boundary of
258     // the permissible color volume, rather than by hard-clipping. This mode of
259     // clipping preserves luminance between the source and the destination, at
260     // the cost of introducing some color distortion in the opposite direction.
261     bool gamut_clipping;
262 };
263 
264 extern const struct pl_color_map_params pl_color_map_default_params;
265 
266 // Maps `vec4 color` from one color space to another color space according
267 // to the parameters (described in greater depth above). If `params` is left
268 // as NULL, it defaults to `&pl_color_map_default_params`. If `prelinearized`
269 // is true, the logic will assume the input has already been linearized by the
270 // caller (e.g. as part of a previous linear light scaling operation).
271 //
272 // If `peak_detect_state` is set to a valid peak detection state object (as
273 // created by `pl_shader_detect_peak`), the detected values will be used in
274 // place of `src.sig_peak` / `src.sig_avg`.
275 //
276 // Note: The peak detection state object is only updated after the shader is
277 // dispatched, so if `pl_shader_detect_peak` is called as part of the same
278 // shader as `pl_shader_color_map`, the results will end up delayed by one
279 // frame. If frame-level accuracy is desired, then users should call
280 // `pl_shader_detect_peak` separately and dispatch the resulting shader
281 // *before* dispatching this one.
282 void pl_shader_color_map(pl_shader sh,
283                          const struct pl_color_map_params *params,
284                          struct pl_color_space src, struct pl_color_space dst,
285                          pl_shader_obj *peak_detect_state,
286                          bool prelinearized);
287 
288 // Applies a set of cone distortion parameters to `vec4 color` in a given color
289 // space. This can be used to simulate color blindness. See `pl_cone_params`
290 // for more information.
291 void pl_shader_cone_distort(pl_shader sh, struct pl_color_space csp,
292                             const struct pl_cone_params *params);
293 
294 enum pl_dither_method {
295     // Dither with blue noise. Very high quality, but requires the use of a
296     // LUT. Warning: Computing a blue noise texture with a large size can be
297     // very slow, however this only needs to be performed once. Even so, using
298     // this with a `lut_size` greater than 6 is generally ill-advised. This is
299     // the preferred/default dither method.
300     PL_DITHER_BLUE_NOISE,
301 
302     // Dither with an ordered (bayer) dither matrix, using a LUT. Low quality,
303     // and since this also uses a LUT, there's generally no advantage to picking
304     // this instead of `PL_DITHER_BLUE_NOISE`. It's mainly there for testing.
305     PL_DITHER_ORDERED_LUT,
306 
307     // The same as `PL_DITHER_ORDERED_LUT`, but uses fixed function math instead
308     // of a LUT. This is faster, but only supports a fixed dither matrix size
309     // of 16x16 (equal to a `lut_size` of 4). Requires GLSL 130+.
310     PL_DITHER_ORDERED_FIXED,
311 
312     // Dither with white noise. This does not require a LUT and is fairly cheap
313     // to compute. Unlike the other modes it doesn't show any repeating
314     // patterns either spatially or temporally, but the downside is that this
315     // is visually fairly jarring due to the presence of low frequencies in the
316     // noise spectrum. Used as a fallback when the above methods are not
317     // available.
318     PL_DITHER_WHITE_NOISE,
319 
320     PL_DITHER_METHOD_COUNT,
321 };
322 
323 struct pl_dither_params {
324     // The source of the dither noise to use.
325     enum pl_dither_method method;
326 
327     // For the dither methods which require the use of a LUT, this controls
328     // the size of the LUT (base 2). If left as NULL, this defaults to 6, which
329     // is equivalent to a 64x64 dither matrix. Must not be larger than 8.
330     int lut_size;
331 
332     // Enables temporal dithering. This reduces the persistence of dithering
333     // artifacts by perturbing the dithering matrix per frame.
334     // Warning: This can cause nasty aliasing artifacts on some LCD screens.
335     bool temporal;
336 };
337 
338 extern const struct pl_dither_params pl_dither_default_params;
339 
340 // Dither the colors to a lower depth, given in bits. This can be used on input
341 // colors of any precision. Basically, this rounds the colors to only linear
342 // multiples of the stated bit depth. The average intensity of the result
343 // will not change (i.e., the dither noise is balanced in both directions).
344 // If `params` is NULL, it defaults to &pl_dither_default_params.
345 //
346 // For the dither methods which require the use of a LUT, `dither_state` must
347 // be set to a valid pointer. To avoid thrashing the resource, users should
348 // avoid trying to re-use the same LUT for different dither configurations. If
349 // passed as NULL, libplacebo will automatically fall back to dither algorithms
350 // that don't require the use of a LUT.
351 //
352 // Warning: This dithering algorithm is not gamma-invariant; so using it for
353 // very low bit depths (below 4 or so) will noticeably increase the brightness
354 // of the resulting image. When doing low bit depth dithering for aesthetic
355 // purposes, it's recommended that the user explicitly (de)linearize the colors
356 // before and after this algorithm.
357 void pl_shader_dither(pl_shader sh, int new_depth,
358                       pl_shader_obj *dither_state,
359                       const struct pl_dither_params *params);
360 
361 PL_API_END
362 
363 #endif // LIBPLACEBO_SHADERS_COLORSPACE_H_
364