summaryrefslogtreecommitdiffstats
path: root/src/include/libplacebo/shaders/icc.h
blob: a4003f406a8b8196b1296afe1c2359577bc9860f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * This file is part of libplacebo.
 *
 * libplacebo is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * libplacebo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with libplacebo.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef LIBPLACEBO_SHADERS_ICC_H_
#define LIBPLACEBO_SHADERS_ICC_H_

// Functions for generating and applying ICC-derived (3D)LUTs

#include <libplacebo/colorspace.h>
#include <libplacebo/shaders.h>

PL_API_BEGIN

struct pl_icc_params {
    // The rendering intent to use, for profiles with multiple intents. A
    // recommended value is PL_INTENT_RELATIVE_COLORIMETRIC for color-accurate
    // video reproduction, or PL_INTENT_PERCEPTUAL for profiles containing
    // meaningful perceptual mapping tables for some more suitable color space
    // like BT.709.
    //
    // If this is set to the special value PL_INTENT_AUTO, will use the
    // preferred intent provided by the profile header.
    enum pl_rendering_intent intent;

    // The size of the 3DLUT to generate. If left as NULL, these individually
    // default to values appropriate for the profile. (Based on internal
    // precision heuristics)
    //
    // Note: Setting this manually is strongly discouraged, as it can result
    // in excessively high 3DLUT sizes where a much smaller LUT would have
    // sufficed.
    int size_r, size_g, size_b;

    // This field can be used to override the detected brightness level of the
    // ICC profile. If you set this to the special value 0 (or a negative
    // number), libplacebo will attempt reading the brightness value from the
    // ICC profile's tagging (if available), falling back to PL_COLOR_SDR_WHITE
    // if unavailable.
    float max_luma;

    // Force black point compensation. May help avoid crushed or raised black
    // points on "improper" profiles containing e.g. colorimetric tables that
    // do not round-trip. Should not be required on well-behaved profiles,
    // or when using PL_INTENT_PERCEPTUAL, but YMMV.
    bool force_bpc;

    // If provided, this pl_cache instance will be used, instead of the
    // GPU-internal cache, to cache the generated 3DLUTs. Note that these can
    // get large, especially for large values of size_{r,g,b}, so the user may
    // wish to split this cache off from the main shader cache. (Optional)
    pl_cache cache;

    // Deprecated legacy caching API. Replaced by `cache`.
    PL_DEPRECATED void *cache_priv;
    PL_DEPRECATED void (*cache_save)(void *priv, uint64_t sig, const uint8_t *cache, size_t size);
    PL_DEPRECATED bool (*cache_load)(void *priv, uint64_t sig, uint8_t *cache, size_t size);
};

#define PL_ICC_DEFAULTS                         \
    .intent = PL_INTENT_RELATIVE_COLORIMETRIC,  \
    .max_luma = PL_COLOR_SDR_WHITE,

#define pl_icc_params(...) (&(struct pl_icc_params) { PL_ICC_DEFAULTS __VA_ARGS__ })
PL_API extern const struct pl_icc_params pl_icc_default_params;

// This object represents a "parsed" ICC profile.
typedef const struct pl_icc_object_t {
    // Provided params, with the `intent` and `size` fields set (as described)
    struct pl_icc_params params;

    // Signature of the corresponding ICC profile.
    uint64_t signature;

    // Detected color space (or UNKNOWN for profiles which don't contain an
    // exact match), with HDR metedata set to the detected gamut and
    // white/black value ranges.
    struct pl_color_space csp;

    // Best estimate of profile gamma. This only serves as a rough guideline.
    float gamma;

    // Smallest containing primary set, always set.
    enum pl_color_primaries containing_primaries;
} *pl_icc_object;

// Attempts opening/parsing the contents of an ICC profile. The resulting
// object is memory managed and may outlive the original profile - access
// to the underlying profile is no longer needed once this returns.
PL_API pl_icc_object pl_icc_open(pl_log log, const struct pl_icc_profile *profile,
                                 const struct pl_icc_params *params);
PL_API void pl_icc_close(pl_icc_object *icc);

// Update an existing pl_icc_object, which may be NULL, replacing it by the
// new profile and parameters (if incompatible).
//
// Returns success. `obj` is set to the created profile, or NULL on error.
//
// Note: If `profile->signature` matches `(*obj)->signature`, or if `profile` is
// NULL, then the existing profile is directly reused, with only the effective
// parameters changing. In this case, `profile->data` is also *not* read from,
// and may safely be NULL.
PL_API bool pl_icc_update(pl_log log, pl_icc_object *obj,
                          const struct pl_icc_profile *profile,
                          const struct pl_icc_params *params);

// Decode the input from the colorspace determined by the attached ICC profile
// to linear light RGB (in the profile's containing primary set). `lut` must be
// set to a shader object that will store the GPU resources associated with the
// generated LUT. The resulting color space will be written to `out_csp`.
PL_API void pl_icc_decode(pl_shader sh, pl_icc_object profile, pl_shader_obj *lut,
                          struct pl_color_space *out_csp);

// Encode the input from linear light RGB (in the profile's containing primary
// set) into the colorspace determined by the attached ICC profile. `lut` must
// be set to a shader object that will store the GPU resources associated with
// the generated LUT.
PL_API void pl_icc_encode(pl_shader sh, pl_icc_object profile, pl_shader_obj *lut);

PL_API_END

#endif // LIBPLACEBO_SHADERS_ICC_H_