Support MCA sound channel tags in MXF/CPL.
[libdcp.git] / src / types.h
1 /*
2     Copyright (C) 2012-2019 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/types.h
35  *  @brief Miscellaneous types.
36  */
37
38 #ifndef LIBDCP_TYPES_H
39 #define LIBDCP_TYPES_H
40
41 #include <libcxml/cxml.h>
42 #include <asdcp/KLV.h>
43 #include <boost/shared_ptr.hpp>
44 #include <boost/function.hpp>
45 #include <string>
46
47 namespace xmlpp {
48         class Element;
49 }
50
51 namespace dcp
52 {
53
54 /** @struct Size
55  *  @brief The integer, two-dimensional size of something.
56  */
57 struct Size
58 {
59         Size ()
60                 : width (0)
61                 , height (0)
62         {}
63
64         Size (int w, int h)
65                 : width (w)
66                 , height (h)
67         {}
68
69         float ratio () const {
70                 return float (width) / height;
71         }
72
73         int width;
74         int height;
75 };
76
77 extern bool operator== (Size const & a, Size const & b);
78 extern bool operator!= (Size const & a, Size const & b);
79 extern std::ostream& operator<< (std::ostream& s, Size const & a);
80
81 /** Identifier for a sound channel */
82 enum Channel {
83         LEFT = 0,      ///< left
84         RIGHT = 1,     ///< right
85         CENTRE = 2,    ///< centre
86         LFE = 3,       ///< low-frequency effects (sub)
87         LS = 4,        ///< left surround
88         RS = 5,        ///< right surround
89         HI = 6,
90         VI = 7,
91         LC = 8,
92         RC = 9,
93         BSL = 10,
94         BSR = 11,
95         MOTION_DATA = 12,
96         SYNC_SIGNAL = 13,
97         SIGN_LANGUAGE = 14,
98         UNUSED = 15,
99         CHANNEL_COUNT = 16
100 };
101
102
103 enum MCASoundField
104 {
105         FIVE_POINT_ONE,
106         SEVEN_POINT_ONE
107 };
108
109
110 extern std::string channel_to_mca_id (Channel c, MCASoundField field);
111 extern Channel mca_id_to_channel (std::string);
112 extern std::string channel_to_mca_name (Channel c, MCASoundField field);
113 extern ASDCP::UL channel_to_mca_universal_label (Channel c, MCASoundField field, ASDCP::Dictionary const* dict);
114
115
116 enum ContentKind
117 {
118         FEATURE,
119         SHORT,
120         TRAILER,
121         TEST,
122         TRANSITIONAL,
123         RATING,
124         TEASER,
125         POLICY,
126         PUBLIC_SERVICE_ANNOUNCEMENT,
127         ADVERTISEMENT,
128         EPISODE,
129         PROMO
130 };
131
132 extern std::string content_kind_to_string (ContentKind kind);
133 extern ContentKind content_kind_from_string (std::string kind);
134
135 enum Effect
136 {
137         NONE,
138         BORDER,
139         SHADOW
140 };
141
142 extern std::string effect_to_string (Effect e);
143 extern Effect string_to_effect (std::string s);
144
145 enum HAlign
146 {
147         HALIGN_LEFT,   ///< horizontal position is distance from left of screen to left of subtitle
148         HALIGN_CENTER, ///< horizontal position is distance from centre of screen to centre of subtitle
149         HALIGN_RIGHT,  ///< horizontal position is distance from right of screen to right of subtitle
150 };
151
152 extern std::string halign_to_string (HAlign a);
153 extern HAlign string_to_halign (std::string s);
154
155 enum VAlign
156 {
157         VALIGN_TOP,    ///< vertical position is distance from top of screen to top of subtitle
158         VALIGN_CENTER, ///< vertical position is distance from centre of screen to centre of subtitle
159         VALIGN_BOTTOM  ///< vertical position is distance from bottom of screen to bottom of subtitle
160 };
161
162 extern std::string valign_to_string (VAlign a);
163 extern VAlign string_to_valign (std::string s);
164
165 /** Direction for subtitle test */
166 enum Direction
167 {
168         DIRECTION_LTR, ///< left-to-right
169         DIRECTION_RTL, ///< right-to-left
170         DIRECTION_TTB, ///< top-to-bottom
171         DIRECTION_BTT  ///< bottom-to-top
172 };
173
174 extern std::string direction_to_string (Direction a);
175 extern Direction string_to_direction (std::string s);
176
177 enum Eye
178 {
179         EYE_LEFT,
180         EYE_RIGHT
181 };
182
183 /** @class Fraction
184  *  @brief A fraction (i.e. a thing with an integer numerator and an integer denominator).
185  */
186 class Fraction
187 {
188 public:
189         /** Construct a fraction of 0/0 */
190         Fraction () : numerator (0), denominator (0) {}
191         explicit Fraction (std::string s);
192         /** Construct a fraction with a specified numerator and denominator.
193          *  @param n Numerator.
194          *  @param d Denominator.
195          */
196         Fraction (int n, int d) : numerator (n), denominator (d) {}
197
198         float as_float () const {
199                 return float (numerator) / denominator;
200         }
201
202         std::string as_string () const;
203
204         int numerator;
205         int denominator;
206 };
207
208 extern bool operator== (Fraction const & a, Fraction const & b);
209 extern bool operator!= (Fraction const & a, Fraction const & b);
210 extern std::ostream& operator<< (std::ostream& s, Fraction const & f);
211
212 /** @struct EqualityOptions
213  *  @brief  A class to describe what "equality" means for a particular test.
214  *
215  *  When comparing things, we want to be able to ignore some differences;
216  *  this class expresses those differences.
217  */
218 struct EqualityOptions
219 {
220         /** Construct an EqualityOptions where nothing at all can differ */
221         EqualityOptions ()
222                 : max_mean_pixel_error (0)
223                 , max_std_dev_pixel_error (0)
224                 , max_audio_sample_error (0)
225                 , cpl_annotation_texts_can_differ (false)
226                 , reel_annotation_texts_can_differ (false)
227                 , reel_hashes_can_differ (false)
228                 , issue_dates_can_differ (false)
229                 , load_font_nodes_can_differ (false)
230                 , keep_going (false)
231         {}
232
233         /** The maximum allowable mean difference in pixel value between two images */
234         double max_mean_pixel_error;
235         /** The maximum standard deviation of the differences in pixel value between two images */
236         double max_std_dev_pixel_error;
237         /** The maximum difference in audio sample value between two soundtracks */
238         int max_audio_sample_error;
239         /** true if the &lt;AnnotationText&gt; nodes of CPLs are allowed to differ */
240         bool cpl_annotation_texts_can_differ;
241         /** true if the &lt;AnnotationText&gt; nodes of Reels are allowed to differ */
242         bool reel_annotation_texts_can_differ;
243         /** true if <Hash>es in Reels can differ */
244         bool reel_hashes_can_differ;
245         /** true if IssueDate nodes can differ */
246         bool issue_dates_can_differ;
247         bool load_font_nodes_can_differ;
248         bool keep_going;
249 };
250
251 /* I've been unable to make mingw happy with ERROR as a symbol, so
252    I'm using a DCP_ prefix here.
253 */
254 enum NoteType {
255         DCP_PROGRESS,
256         DCP_ERROR,
257         DCP_NOTE
258 };
259
260 enum Standard {
261         INTEROP,
262         SMPTE
263 };
264
265 enum Formulation {
266         MODIFIED_TRANSITIONAL_1,
267         MULTIPLE_MODIFIED_TRANSITIONAL_1,
268         DCI_ANY,
269         DCI_SPECIFIC,
270         /** For testing: adds no AuthorizedDeviceInfo tag */
271         MODIFIED_TRANSITIONAL_TEST
272 };
273
274 /** @class Colour
275  *  @brief An RGB colour.
276  */
277 class Colour
278 {
279 public:
280         Colour ();
281         Colour (int r_, int g_, int b_);
282         explicit Colour (std::string argb_hex);
283
284         int r; ///< red component, from 0 to 255
285         int g; ///< green component, from 0 to 255
286         int b; ///< blue component, from 0 to 255
287
288         std::string to_rgb_string () const;
289         std::string to_argb_string () const;
290 };
291
292 extern bool operator== (Colour const & a, Colour const & b);
293 extern bool operator!= (Colour const & a, Colour const & b);
294 extern std::ostream & operator<< (std::ostream & s, Colour const & c);
295
296 typedef boost::function<void (NoteType, std::string)> NoteHandler;
297
298 /** Maximum absolute difference between dcp::SubtitleString::aspect_adjust values that
299  *  are considered equal.
300  */
301 const float ASPECT_ADJUST_EPSILON = 1e-3;
302
303 /** Maximum absolute difference between dcp::SubtitleString alignment values that
304  *  are considered equal.
305  */
306 const float ALIGN_EPSILON = 1e-3;
307
308 enum Marker {
309         FFOC, ///< first frame of composition
310         LFOC, ///< last frame of composition
311         FFTC, ///< first frame of title credits
312         LFTC, ///< last frame of title credits
313         FFOI, ///< first frame of intermission
314         LFOI, ///< last frame of intermission
315         FFEC, ///< first frame of end credits
316         LFEC, ///< last frame of end credits
317         FFMC, ///< first frame of moving credits
318         LFMC  ///< last frame of moving credits
319 };
320
321 std::string marker_to_string (Marker);
322 Marker marker_from_string (std::string);
323
324 class Rating
325 {
326 public:
327         Rating (std::string agency_, std::string label_)
328                 : agency (agency_)
329                 , label (label_)
330         {}
331
332         explicit Rating (cxml::ConstNodePtr node);
333
334         void as_xml (xmlpp::Element* parent) const;
335
336         /** URI of the agency issuing the rating */
337         std::string agency;
338         /** Rating (e.g. PG, PG-13, 12A etc) */
339         std::string label;
340 };
341
342 extern bool operator== (Rating const & a, Rating const & b);
343 extern std::ostream& operator<< (std::ostream& s, Rating const & r);
344
345
346 enum Status
347 {
348         FINAL, ///< final version
349         TEMP,  ///< temporary version (picture/sound unfinished)
350         PRE    ///< pre-release (picture/sound finished)
351 };
352
353
354 extern std::string status_to_string (Status s);
355 extern Status string_to_status (std::string s);
356
357
358 class ContentVersion
359 {
360 public:
361         ContentVersion ();
362
363         explicit ContentVersion (cxml::ConstNodePtr node);
364
365         explicit ContentVersion (std::string label_text_);
366
367         ContentVersion (std::string id_, std::string label_text_)
368                 : id (id_)
369                 , label_text (label_text_)
370         {}
371
372         void as_xml (xmlpp::Element* parent) const;
373
374         std::string id;
375         std::string label_text;
376 };
377
378
379 class Luminance
380 {
381 public:
382         enum Unit {
383                 CANDELA_PER_SQUARE_METRE,
384                 FOOT_LAMBERT
385         };
386
387         Luminance (cxml::ConstNodePtr node);
388
389         Luminance (float value, Unit unit);
390
391         void set_value (float v);
392         void set_unit (Unit u) {
393                 _unit = u;
394         }
395
396         float value () const {
397                 return _value;
398         }
399
400         Unit unit () const {
401                 return _unit;
402         }
403
404         void as_xml (xmlpp::Element* parent, std::string ns) const;
405
406         static std::string unit_to_string (Unit u);
407         static Unit string_to_unit (std::string u);
408
409 private:
410         float _value;
411         Unit _unit;
412 };
413
414 bool operator== (Luminance const& a, Luminance const& b);
415
416
417 class MainSoundConfiguration
418 {
419 public:
420         MainSoundConfiguration (std::string);
421         MainSoundConfiguration (MCASoundField field_, int channels);
422
423         MCASoundField field () const {
424                 return _field;
425         }
426
427         int channels () const {
428                 return _channels.size();
429         }
430
431         boost::optional<Channel> mapping (int index) const;
432         void set_mapping (int index, Channel channel);
433
434         std::string to_string () const;
435
436 private:
437         MCASoundField _field;
438         std::vector<boost::optional<Channel> > _channels;
439 };
440
441
442 }
443
444 #endif