Fix tests to actually check the results in several cases.
[libdcp.git] / src / colour_conversion.h
1 /*
2     Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
6     libdcp is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     libdcp is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
18
19     In addition, as a special exception, the copyright holders give
20     permission to link the code of portions of this program with the
21     OpenSSL library under certain conditions as described in each
22     individual source file, and distribute linked combinations
23     including the two.
24
25     You must obey the GNU General Public License in all respects
26     for all of the code used other than OpenSSL.  If you modify
27     file(s) with this exception, you may extend this exception to your
28     version of the file(s), but you are not obligated to do so.  If you
29     do not wish to do so, delete this exception statement from your
30     version.  If you delete this exception statement from all source
31     files in the program, then also delete it here.
32 */
33
34 /** @file  src/colour_conversion.h
35  *  @brief ColourConversion class.
36  */
37
38 #ifndef DCP_COLOUR_CONVERSION_H
39 #define DCP_COLOUR_CONVERSION_H
40
41 #include "chromaticity.h"
42 #include <memory>
43 #if BOOST_VERSION >= 106400
44 #include <boost/serialization/array_wrapper.hpp>
45 #endif
46 #include <boost/numeric/ublas/matrix.hpp>
47 #include <boost/optional.hpp>
48
49 namespace dcp {
50
51 class TransferFunction;
52
53 enum YUVToRGB {
54         YUV_TO_RGB_REC601,
55         YUV_TO_RGB_REC709,
56         YUV_TO_RGB_COUNT
57 };
58
59 /** @class ColourConversion
60  *  @brief A representation of all the parameters involved the colourspace conversion
61  *  of a YUV image to XYZ (via RGB).
62  */
63 class ColourConversion
64 {
65 public:
66         ColourConversion ()
67                 : _yuv_to_rgb (YUV_TO_RGB_REC601)
68         {}
69
70         ColourConversion (
71                 std::shared_ptr<const TransferFunction> in,
72                 YUVToRGB yuv_to_rgb,
73                 Chromaticity red,
74                 Chromaticity green,
75                 Chromaticity blue,
76                 Chromaticity white,
77                 boost::optional<Chromaticity> adjusted_white,
78                 std::shared_ptr<const TransferFunction> out
79                 );
80
81         std::shared_ptr<const TransferFunction> in () const {
82                 return _in;
83         }
84
85         YUVToRGB yuv_to_rgb () const {
86                 return _yuv_to_rgb;
87         }
88
89         Chromaticity red () const {
90                 return _red;
91         }
92
93         Chromaticity green () const {
94                 return _green;
95         }
96
97         Chromaticity blue () const {
98                 return _blue;
99         }
100
101         Chromaticity white () const {
102                 return _white;
103         }
104
105         boost::optional<Chromaticity> adjusted_white () const {
106                 return _adjusted_white;
107         }
108
109         std::shared_ptr<const TransferFunction> out () const {
110                 return _out;
111         }
112
113         void set_in (std::shared_ptr<const TransferFunction> f) {
114                 _in = f;
115         }
116
117         void set_yuv_to_rgb (YUVToRGB y) {
118                 _yuv_to_rgb = y;
119         }
120
121         void set_red (Chromaticity red) {
122                 _red = red;
123         }
124
125         void set_green (Chromaticity green) {
126                 _green = green;
127         }
128
129         void set_blue (Chromaticity blue) {
130                 _blue = blue;
131         }
132
133         void set_white (Chromaticity white) {
134                 _white = white;
135         }
136
137         void set_adjusted_white (Chromaticity adjusted_white) {
138                 _adjusted_white = adjusted_white;
139         }
140
141         void unset_adjusted_white () {
142                 _adjusted_white = boost::optional<Chromaticity> ();
143         }
144
145         void set_out (std::shared_ptr<const TransferFunction> f) {
146                 _out = f;
147         }
148
149         bool about_equal (ColourConversion const & other, float epsilon) const;
150
151         boost::numeric::ublas::matrix<double> rgb_to_xyz () const;
152         boost::numeric::ublas::matrix<double> xyz_to_rgb () const;
153         boost::numeric::ublas::matrix<double> bradford () const;
154
155         static ColourConversion const & srgb_to_xyz ();
156         static ColourConversion const & rec601_to_xyz ();
157         static ColourConversion const & rec709_to_xyz ();
158         static ColourConversion const & p3_to_xyz ();
159         static ColourConversion const & rec1886_to_xyz ();
160         static ColourConversion const & rec2020_to_xyz ();
161         static ColourConversion const & s_gamut3_to_xyz ();
162
163 protected:
164         /** Input transfer function (probably a gamma function, or something similar) */
165         std::shared_ptr<const TransferFunction> _in;
166         /** Conversion to use from YUV to RGB */
167         YUVToRGB _yuv_to_rgb;
168         Chromaticity _red;
169         Chromaticity _green;
170         Chromaticity _blue;
171         Chromaticity _white;
172         /** White point that we are adjusting to using a Bradford matrix */
173         boost::optional<Chromaticity> _adjusted_white;
174         /** Output transfer function (probably an inverse gamma function, or something similar) */
175         std::shared_ptr<const TransferFunction> _out;
176 };
177
178 }
179
180 #endif