Use 2.222222 for the power in the modified Rec. 709 input gamma
[libdcp.git] / src / colour_conversion.cc
1 /*
2     Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program 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 General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "colour_conversion.h"
21 #include "gamma_transfer_function.h"
22 #include "modified_gamma_transfer_function.h"
23 #include "colour_matrix.h"
24
25 using boost::shared_ptr;
26 using namespace dcp;
27
28 ColourConversion const &
29 ColourConversion::srgb_to_xyz ()
30 {
31         static ColourConversion* c = new ColourConversion (
32                 shared_ptr<const TransferFunction> (new ModifiedGammaTransferFunction (false, 2.4, 0.04045, 0.055, 12.92)),
33                 dcp::colour_matrix::rgb_to_xyz,
34                 shared_ptr<const TransferFunction> (new GammaTransferFunction (true, 2.6))
35                 );
36         return *c;
37 }
38
39 ColourConversion const &
40 ColourConversion::xyz_to_srgb ()
41 {
42         static ColourConversion* c = new ColourConversion (
43                 shared_ptr<const TransferFunction> (new GammaTransferFunction (false, 2.6)),
44                 dcp::colour_matrix::xyz_to_rgb,
45                 shared_ptr<const TransferFunction> (new ModifiedGammaTransferFunction (true, 2.4, 0.04045, 0.055, 12.92))
46                 );
47         return *c;
48 }
49
50 ColourConversion const &
51 ColourConversion::rec709_to_xyz ()
52 {
53         static ColourConversion* c = new ColourConversion (
54                 shared_ptr<const TransferFunction> (new ModifiedGammaTransferFunction (false, 1 / 0.45, 0.081, 0.099, 4.5)),
55                 dcp::colour_matrix::rgb_to_xyz,
56                 shared_ptr<const TransferFunction> (new GammaTransferFunction (true, 2.6))
57                 );
58         return *c;
59 }
60
61 ColourConversion::ColourConversion (
62         shared_ptr<const TransferFunction> in,
63         double const matrix[3][3],
64         shared_ptr<const TransferFunction> out
65         )
66         : _in (in)
67         , _matrix (3, 3)
68         , _out (out)
69 {
70         for (int i = 0; i < 3; ++i) {
71                 for (int j = 0; j < 3; ++j) {
72                         _matrix (i, j) = matrix[i][j];
73                 }
74         }
75 }
76
77 bool
78 ColourConversion::about_equal (ColourConversion const & other, float epsilon) const
79 {
80         for (int i = 0; i < 3; ++i) {
81                 for (int j = 0; j < 3; ++j) {
82                         if (fabs (_matrix(i, j) - other._matrix(i, j)) > epsilon) {
83                                 return false;
84                         }
85                 }
86         }
87
88         return _in->about_equal (other._in, epsilon) && _out->about_equal (other._out, epsilon);
89 }