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