]> git.sesse.net Git - movit/blob - gamma_expansion_effect.cpp
Calculate the RGB-to-XYZ matrix ourselves instead of using a “magic” one from Wikipedia.
[movit] / gamma_expansion_effect.cpp
1 #include <math.h>
2 #include <assert.h>
3
4 #include "gamma_expansion_effect.h"
5 #include "util.h"
6
7 GammaExpansionEffect::GammaExpansionEffect()
8         : source_curve(GAMMA_LINEAR)
9 {
10         register_int("source_curve", (int *)&source_curve);
11         memset(expansion_curve, 0, sizeof(expansion_curve));
12         register_1d_texture("expansion_curve_tex", expansion_curve, EXPANSION_CURVE_SIZE);
13 }
14
15 std::string GammaExpansionEffect::output_fragment_shader()
16 {
17         if (source_curve == GAMMA_LINEAR) {
18                 return read_file("identity.frag");
19         }
20         if (source_curve == GAMMA_sRGB) {
21                 for (unsigned i = 0; i < EXPANSION_CURVE_SIZE; ++i) {
22                         float x = i / (float)(EXPANSION_CURVE_SIZE - 1);
23                         if (x < 0.04045f) {
24                                 expansion_curve[i] = (1.0/12.92f) * x;
25                         } else {
26                                 expansion_curve[i] = pow((x + 0.055) * (1.0/1.055f), 2.4);
27                         }
28                 }
29                 invalidate_1d_texture("expansion_curve_tex");
30                 return read_file("gamma_expansion_effect.frag");
31         }
32         if (source_curve == GAMMA_REC_709 ||  // Also includes Rec. 601, and 10-bit Rec. 2020.
33             source_curve == GAMMA_REC_2020_12_BIT) {
34                 // Rec. 2020, page 3.
35                 float alpha, beta;
36                 if (source_curve == GAMMA_REC_2020_12_BIT) {
37                         alpha = 1.0993f;
38                         beta = 0.0181f;
39                 } else {
40                         alpha = 1.099f;
41                         beta = 0.018f;
42                 }
43                 for (unsigned i = 0; i < EXPANSION_CURVE_SIZE; ++i) {
44                         float x = i / (float)(EXPANSION_CURVE_SIZE - 1);
45                         if (x < beta * 4.5f) {
46                                 expansion_curve[i] = (1.0/4.5f) * x;
47                         } else {
48                                 expansion_curve[i] = pow((x + (alpha - 1.0f)) / alpha, 1.0f/0.45f);
49                         }
50                 }
51                 invalidate_1d_texture("expansion_curve_tex");
52                 return read_file("gamma_expansion_effect.frag");
53         }
54         assert(false);
55 }