be960699d5870350655d7fd170aedec785b397d8
[libdcp.git] / test / tests.cc
1 /*
2     Copyright (C) 2012 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 <cmath>
21 #include <boost/filesystem.hpp>
22 #include "KM_prng.h"
23 #include "dcp.h"
24 #include "util.h"
25 #include "metadata.h"
26 #include "types.h"
27 #include "exceptions.h"
28 #include "subtitle_asset.h"
29 #include "picture_asset.h"
30 #include "sound_asset.h"
31 #include "reel.h"
32
33 #define BOOST_TEST_DYN_LINK
34 #define BOOST_TEST_MODULE libdcp_test
35 #include <boost/test/unit_test.hpp>
36
37 using std::string;
38 using std::vector;
39 using std::list;
40 using boost::shared_ptr;
41
42 string
43 j2c (int)
44 {
45         return "test/data/32x32_red_square.j2c";
46 }
47
48 string
49 wav (libdcp::Channel)
50 {
51         return "test/data/1s_24-bit_48k_silence.wav";
52 }
53                 
54
55 BOOST_AUTO_TEST_CASE (dcp_test)
56 {
57         Kumu::libdcp_test = true;
58         
59         libdcp::Metadata* t = libdcp::Metadata::instance ();
60         t->issuer = "OpenDCP 0.0.25";
61         t->creator = "OpenDCP 0.0.25";
62         t->company_name = "OpenDCP";
63         t->product_name = "OpenDCP";
64         t->product_version = "0.0.25";
65         t->issue_date = "2012-07-17T04:45:18+00:00";
66         boost::filesystem::remove_all ("build/test/foo");
67         boost::filesystem::create_directories ("build/test/foo");
68         libdcp::DCP d ("build/test/foo");
69         shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("build/test/foo", "A Test DCP", libdcp::FEATURE, 24, 24));
70
71         shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset (
72                                                          j2c,
73                                                          "build/test/foo",
74                                                          "video.mxf",
75                                                          &d.Progress,
76                                                          24,
77                                                          24,
78                                                          32,
79                                                          32
80                                                          ));
81
82         shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
83                                                    wav,
84                                                    "build/test/foo",
85                                                    "audio.mxf",
86                                                    &(d.Progress),
87                                                    24,
88                                                    24,
89                                                    0,
90                                                    2
91                                                    ));
92         
93         cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
94         d.add_cpl (cpl);
95
96         d.write_xml ();
97 }
98
99 BOOST_AUTO_TEST_CASE (error_test)
100 {
101         libdcp::DCP d ("build/test/bar");
102         vector<string> p;
103         p.push_back ("frobozz");
104
105         BOOST_CHECK_THROW (new libdcp::MonoPictureAsset (p, "build/test/bar", "video.mxf", &d.Progress, 24, 24, 32, 32), libdcp::FileError);
106         BOOST_CHECK_THROW (new libdcp::SoundAsset (p, "build/test/bar", "audio.mxf", &d.Progress, 24, 24, 0), libdcp::FileError);
107 }
108
109 BOOST_AUTO_TEST_CASE (read_dcp)
110 {
111         libdcp::DCP d ("test/ref/DCP");
112         d.read ();
113
114         list<shared_ptr<const libdcp::CPL> > cpls = d.cpls ();
115         BOOST_CHECK_EQUAL (cpls.size(), 1);
116
117         BOOST_CHECK_EQUAL (cpls.front()->name(), "A Test DCP");
118         BOOST_CHECK_EQUAL (cpls.front()->content_kind(), libdcp::FEATURE);
119         BOOST_CHECK_EQUAL (cpls.front()->frames_per_second(), 24);
120         BOOST_CHECK_EQUAL (cpls.front()->length(), 24);
121 }
122         
123 BOOST_AUTO_TEST_CASE (subtitles1)
124 {
125         libdcp::SubtitleAsset subs ("test/data", "subs1.xml");
126
127         BOOST_CHECK_EQUAL (subs.language(), "French");
128
129         list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 6, 1));
130         BOOST_CHECK_EQUAL (s.size(), 1);
131         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
132                                    "Arial",
133                                    false,
134                                    libdcp::Color (255, 255, 255),
135                                    39,
136                                    libdcp::Time (0, 0, 5, 198),
137                                    libdcp::Time (0, 0, 7, 115),
138                                    15,
139                                    libdcp::BOTTOM,
140                                    "My jacket was Idi Amin's",
141                                    libdcp::BORDER,
142                                    libdcp::Color (0, 0, 0),
143                                    libdcp::Time (0, 0, 0, 1),
144                                    libdcp::Time (0, 0, 0, 1)
145                                    ));
146                                                          
147         s = subs.subtitles_at (libdcp::Time (0, 0, 7, 190));
148         BOOST_CHECK_EQUAL (s.size(), 2);
149         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
150                                    "Arial",
151                                    true,
152                                    libdcp::Color (255, 255, 255),
153                                    39,
154                                    libdcp::Time (0, 0, 7, 177),
155                                    libdcp::Time (0, 0, 11, 31),
156                                    21,
157                                    libdcp::BOTTOM,
158                                    "My corset was H.M. The Queen's",
159                                    libdcp::BORDER,
160                                    libdcp::Color (0, 0, 0),
161                                    libdcp::Time (0, 0, 0, 1),
162                                    libdcp::Time (0, 0, 0, 1)
163                                    ));
164         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
165                                    "Arial",
166                                    false,
167                                    libdcp::Color (255, 255, 255),
168                                    39,
169                                    libdcp::Time (0, 0, 7, 177),
170                                    libdcp::Time (0, 0, 11, 31),
171                                    15,
172                                    libdcp::BOTTOM,
173                                    "My large wonderbra",
174                                    libdcp::BORDER,
175                                    libdcp::Color (0, 0, 0),
176                                    libdcp::Time (0, 0, 0, 1),
177                                    libdcp::Time (0, 0, 0, 1)
178                                    ));
179
180         s = subs.subtitles_at (libdcp::Time (0, 0, 11, 95));
181         BOOST_CHECK_EQUAL (s.size(), 1);
182         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
183                                    "Arial",
184                                    false,
185                                    libdcp::Color (255, 255, 255),
186                                    39,
187                                    libdcp::Time (0, 0, 11, 94),
188                                    libdcp::Time (0, 0, 13, 63),
189                                    15,
190                                    libdcp::BOTTOM,
191                                    "Once belonged to the Shah",
192                                    libdcp::BORDER,
193                                    libdcp::Color (0, 0, 0),
194                                    libdcp::Time (0, 0, 0, 1),
195                                    libdcp::Time (0, 0, 0, 1)
196                                    ));
197
198         s = subs.subtitles_at (libdcp::Time (0, 0, 14, 42));
199         BOOST_CHECK_EQUAL (s.size(), 1);
200         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
201                                    "Arial",
202                                    false,
203                                    libdcp::Color (255, 255, 255),
204                                    39,
205                                    libdcp::Time (0, 0, 13, 104),
206                                    libdcp::Time (0, 0, 15, 177),
207                                    15,
208                                    libdcp::BOTTOM,
209                                    "And these are Roy Hattersley's jeans",
210                                    libdcp::BORDER,
211                                    libdcp::Color (0, 0, 0),
212                                    libdcp::Time (0, 0, 0, 1),
213                                    libdcp::Time (0, 0, 0, 1)
214                                    ));
215 }
216
217 BOOST_AUTO_TEST_CASE (subtitles2)
218 {
219         libdcp::SubtitleAsset subs ("test/data", "subs2.xml");
220
221         list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 42, 100));
222         BOOST_CHECK_EQUAL (s.size(), 2);
223         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
224                                    "Arial",
225                                    true,
226                                    libdcp::Color (255, 255, 255),
227                                    42,
228                                    libdcp::Time (0, 0, 41, 62),
229                                    libdcp::Time (0, 0, 43, 52),
230                                    89,
231                                    libdcp::TOP,
232                                    "At afternoon tea with John Peel",
233                                    libdcp::BORDER,
234                                    libdcp::Color (0, 0, 0),
235                                    libdcp::Time (0, 0, 0, 0),
236                                    libdcp::Time (0, 0, 0, 0)
237                                    ));
238         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
239                                    "Arial",
240                                    true,
241                                    libdcp::Color (255, 255, 255),
242                                    42,
243                                    libdcp::Time (0, 0, 41, 62),
244                                    libdcp::Time (0, 0, 43, 52),
245                                    95,
246                                    libdcp::TOP,
247                                    "I enquired if his accent was real",
248                                    libdcp::BORDER,
249                                    libdcp::Color (0, 0, 0),
250                                    libdcp::Time (0, 0, 0, 0),
251                                    libdcp::Time (0, 0, 0, 0)
252                                    ));
253
254         s = subs.subtitles_at (libdcp::Time (0, 0, 50, 50));
255         BOOST_CHECK_EQUAL (s.size(), 2);
256         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
257                                    "Arial",
258                                    true,
259                                    libdcp::Color (255, 255, 255),
260                                    42,
261                                    libdcp::Time (0, 0, 50, 42),
262                                    libdcp::Time (0, 0, 52, 21),
263                                    89,
264                                    libdcp::TOP,
265                                    "He said \"out of the house",
266                                    libdcp::BORDER,
267                                    libdcp::Color (0, 0, 0),
268                                    libdcp::Time (0, 0, 0, 0),
269                                    libdcp::Time (0, 0, 0, 0)
270                                    ));
271         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
272                                    "Arial",
273                                    true,
274                                    libdcp::Color (255, 255, 255),
275                                    42,
276                                    libdcp::Time (0, 0, 50, 42),
277                                    libdcp::Time (0, 0, 52, 21),
278                                    95,
279                                    libdcp::TOP,
280                                    "I'm incredibly scouse",
281                                    libdcp::BORDER,
282                                    libdcp::Color (0, 0, 0),
283                                    libdcp::Time (0, 0, 0, 0),
284                                    libdcp::Time (0, 0, 0, 0)
285                                    ));
286
287         s = subs.subtitles_at (libdcp::Time (0, 1, 2, 300));
288         BOOST_CHECK_EQUAL (s.size(), 2);
289         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
290                                    "Arial",
291                                    true,
292                                    libdcp::Color (255, 255, 255),
293                                    42,
294                                    libdcp::Time (0, 1, 2, 208),
295                                    libdcp::Time (0, 1, 4, 10),
296                                    89,
297                                    libdcp::TOP,
298                                    "At home it depends how I feel.\"",
299                                    libdcp::BORDER,
300                                    libdcp::Color (0, 0, 0),
301                                    libdcp::Time (0, 0, 0, 0),
302                                    libdcp::Time (0, 0, 0, 0)
303                                    ));
304         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
305                                    "Arial",
306                                    true,
307                                    libdcp::Color (255, 255, 255),
308                                    42,
309                                    libdcp::Time (0, 1, 2, 208),
310                                    libdcp::Time (0, 1, 4, 10),
311                                    95,
312                                    libdcp::TOP,
313                                    "I spent a long weekend in Brighton",
314                                    libdcp::BORDER,
315                                    libdcp::Color (0, 0, 0),
316                                    libdcp::Time (0, 0, 0, 0),
317                                    libdcp::Time (0, 0, 0, 0)
318                                    ));
319
320         s = subs.subtitles_at (libdcp::Time (0, 1, 15, 50));
321         BOOST_CHECK_EQUAL (s.size(), 2);
322         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
323                                    "Arial",
324                                    true,
325                                    libdcp::Color (255, 255, 255),
326                                    42,
327                                    libdcp::Time (0, 1, 15, 42),
328                                    libdcp::Time (0, 1, 16, 42),
329                                    89,
330                                    libdcp::TOP,
331                                    "With the legendary Miss Enid Blyton",
332                                    libdcp::BORDER,
333                                    libdcp::Color (0, 0, 0),
334                                    libdcp::Time (0, 0, 0, 0),
335                                    libdcp::Time (0, 0, 0, 0)
336                                    ));
337         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
338                                    "Arial",
339                                    true,
340                                    libdcp::Color (255, 255, 255),
341                                    42,
342                                    libdcp::Time (0, 1, 15, 42),
343                                    libdcp::Time (0, 1, 16, 42),
344                                    95,
345                                    libdcp::TOP,
346                                    "She said \"you be Noddy",
347                                    libdcp::BORDER,
348                                    libdcp::Color (0, 0, 0),
349                                    libdcp::Time (0, 0, 0, 0),
350                                    libdcp::Time (0, 0, 0, 0)
351                                    ));
352
353         s = subs.subtitles_at (libdcp::Time (0, 1, 27, 200));
354         BOOST_CHECK_EQUAL (s.size(), 2);
355         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
356                                    "Arial",
357                                    true,
358                                    libdcp::Color (255, 255, 255),
359                                    42,
360                                    libdcp::Time (0, 1, 27, 115),
361                                    libdcp::Time (0, 1, 28, 208),
362                                    89,
363                                    libdcp::TOP,
364                                    "That curious creature the Sphinx",
365                                    libdcp::BORDER,
366                                    libdcp::Color (0, 0, 0),
367                                    libdcp::Time (0, 0, 0, 0),
368                                    libdcp::Time (0, 0, 0, 0)
369                                    ));
370         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
371                                    "Arial",
372                                    true,
373                                    libdcp::Color (255, 255, 255),
374                                    42,
375                                    libdcp::Time (0, 1, 27, 115),
376                                    libdcp::Time (0, 1, 28, 208),
377                                    95,
378                                    libdcp::TOP,
379                                    "Is smarter than anyone thinks",
380                                    libdcp::BORDER,
381                                    libdcp::Color (0, 0, 0),
382                                    libdcp::Time (0, 0, 0, 0),
383                                    libdcp::Time (0, 0, 0, 0)
384                                    ));
385
386         s = subs.subtitles_at (libdcp::Time (0, 1, 42, 300));
387         BOOST_CHECK_EQUAL (s.size(), 2);
388         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
389                                    "Arial",
390                                    false,
391                                    libdcp::Color (255, 255, 255),
392                                    42,
393                                    libdcp::Time (0, 1, 42, 229),
394                                    libdcp::Time (0, 1, 45, 62),
395                                    89,
396                                    libdcp::TOP,
397                                    "It sits there and smirks",
398                                    libdcp::BORDER,
399                                    libdcp::Color (0, 0, 0),
400                                    libdcp::Time (0, 0, 0, 0),
401                                    libdcp::Time (0, 0, 0, 0)
402                                    ));
403         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
404                                    "Arial",
405                                    false,
406                                    libdcp::Color (255, 255, 255),
407                                    42,
408                                    libdcp::Time (0, 1, 42, 229),
409                                    libdcp::Time (0, 1, 45, 62),
410                                    95,
411                                    libdcp::TOP,
412                                    "And you don't think it works",
413                                    libdcp::BORDER,
414                                    libdcp::Color (0, 0, 0),
415                                    libdcp::Time (0, 0, 0, 0),
416                                    libdcp::Time (0, 0, 0, 0)
417                                    ));
418
419         s = subs.subtitles_at (libdcp::Time (0, 1, 45, 200));
420         BOOST_CHECK_EQUAL (s.size(), 2);
421         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
422                                    "Arial",
423                                    false,
424                                    libdcp::Color (255, 255, 255),
425                                    42,
426                                    libdcp::Time (0, 1, 45, 146),
427                                    libdcp::Time (0, 1, 47, 94),
428                                    89,
429                                    libdcp::TOP,
430                                    "Then when you're not looking, it winks.",
431                                    libdcp::BORDER,
432                                    libdcp::Color (0, 0, 0),
433                                    libdcp::Time (0, 0, 0, 0),
434                                    libdcp::Time (0, 0, 0, 0)
435                                    ));
436         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
437                                    "Arial",
438                                    false,
439                                    libdcp::Color (255, 255, 255),
440                                    42,
441                                    libdcp::Time (0, 1, 45, 146),
442                                    libdcp::Time (0, 1, 47, 94),
443                                    95,
444                                    libdcp::TOP,
445                                    "When it snows you will find Sister Sledge",
446                                    libdcp::BORDER,
447                                    libdcp::Color (0, 0, 0),
448                                    libdcp::Time (0, 0, 0, 0),
449                                    libdcp::Time (0, 0, 0, 0)
450                                    ));
451
452         s = subs.subtitles_at (libdcp::Time (0, 1, 47, 249));
453         BOOST_CHECK_EQUAL (s.size(), 2);
454         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
455                                    "Arial",
456                                    false,
457                                    libdcp::Color (255, 255, 255),
458                                    42,
459                                    libdcp::Time (0, 1, 47, 146),
460                                    libdcp::Time (0, 1, 48, 167),
461                                    89,
462                                    libdcp::TOP,
463                                    "Out mooning, at night, on the ledge",
464                                    libdcp::BORDER,
465                                    libdcp::Color (0, 0, 0),
466                                    libdcp::Time (0, 0, 0, 0),
467                                    libdcp::Time (0, 0, 0, 0)
468                                    ));
469         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
470                                    "Arial",
471                                    false,
472                                    libdcp::Color (255, 255, 255),
473                                    42,
474                                    libdcp::Time (0, 1, 47, 146),
475                                    libdcp::Time (0, 1, 48, 167),
476                                    95,
477                                    libdcp::TOP,
478                                    "One storey down",
479                                    libdcp::BORDER,
480                                    libdcp::Color (0, 0, 0),
481                                    libdcp::Time (0, 0, 0, 0),
482                                    libdcp::Time (0, 0, 0, 0)
483                                    ));
484
485         s = subs.subtitles_at (libdcp::Time (0, 2, 6, 210));
486         BOOST_CHECK_EQUAL (s.size(), 2);
487         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
488                                    "Arial",
489                                    true,
490                                    libdcp::Color (255, 255, 255),
491                                    42,
492                                    libdcp::Time (0, 2, 5, 208),
493                                    libdcp::Time (0, 2, 7, 31),
494                                    89,
495                                    libdcp::TOP,
496                                    "HELLO",
497                                    libdcp::BORDER,
498                                    libdcp::Color (0, 0, 0),
499                                    libdcp::Time (0, 0, 0, 0),
500                                    libdcp::Time (0, 0, 0, 0)
501                                    ));
502         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
503                                    "Arial",
504                                    true,
505                                    libdcp::Color (255, 255, 255),
506                                    42,
507                                    libdcp::Time (0, 2, 5, 208),
508                                    libdcp::Time (0, 2, 7, 31),
509                                    95,
510                                    libdcp::TOP,
511                                    "WORLD",
512                                    libdcp::BORDER,
513                                    libdcp::Color (0, 0, 0),
514                                    libdcp::Time (0, 0, 0, 0),
515                                    libdcp::Time (0, 0, 0, 0)
516                                    ));
517
518         
519         
520 }
521
522 BOOST_AUTO_TEST_CASE (dcp_time)
523 {
524         libdcp::Time t (977143, 24);
525
526         BOOST_CHECK_EQUAL (t.t, 73);
527         BOOST_CHECK_EQUAL (t.s, 34);
528         BOOST_CHECK_EQUAL (t.m, 18);
529         BOOST_CHECK_EQUAL (t.h, 11);
530         BOOST_CHECK_EQUAL (t.to_string(), "11:18:34:73");
531         BOOST_CHECK_EQUAL (t.to_ticks(), 1017923);
532
533         libdcp::Time a (3, 2, 3, 4);
534         libdcp::Time b (2, 3, 4, 5);
535
536         libdcp::Time r = a - b;
537         BOOST_CHECK_EQUAL (r.h, 0);
538         BOOST_CHECK_EQUAL (r.m, 58);
539         BOOST_CHECK_EQUAL (r.s, 58);
540         BOOST_CHECK_EQUAL (r.t, 249);
541         BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:249");
542         BOOST_CHECK_EQUAL (r.to_ticks(), 88699);
543
544         a = libdcp::Time (1, 58, 56, 240);
545         b = libdcp::Time (1, 7, 12, 120);
546         r = a + b;
547         BOOST_CHECK_EQUAL (r.h, 3);
548         BOOST_CHECK_EQUAL (r.m, 6);
549         BOOST_CHECK_EQUAL (r.s, 9);
550         BOOST_CHECK_EQUAL (r.t, 110);
551         BOOST_CHECK_EQUAL (r.to_string(), "3:6:9:110");
552         BOOST_CHECK_EQUAL (r.to_ticks(), 279335);
553
554         a = libdcp::Time (24, 12, 6, 3);
555         b = libdcp::Time (16, 8, 4, 2);
556         BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
557 }
558
559 BOOST_AUTO_TEST_CASE (color)
560 {
561         libdcp::Color c ("FFFF0000");
562
563         BOOST_CHECK_EQUAL (c.r, 255);
564         BOOST_CHECK_EQUAL (c.g, 0);
565         BOOST_CHECK_EQUAL (c.b, 0);
566         BOOST_CHECK_EQUAL (c.to_argb_string(), "FFFF0000");
567
568         c = libdcp::Color ("FF00FF00");
569
570         BOOST_CHECK_EQUAL (c.r, 0);
571         BOOST_CHECK_EQUAL (c.g, 255);
572         BOOST_CHECK_EQUAL (c.b, 0);
573         BOOST_CHECK_EQUAL (c.to_argb_string(), "FF00FF00");
574
575         c = libdcp::Color ("FF0000FF");
576
577         BOOST_CHECK_EQUAL (c.r, 0);
578         BOOST_CHECK_EQUAL (c.g, 0);
579         BOOST_CHECK_EQUAL (c.b, 255);
580         BOOST_CHECK_EQUAL (c.to_argb_string(), "FF0000FF");
581         
582 }