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