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