Fix subtitle parser to cope with
[libdcp.git] / test / subtitle_tests.cc
1 /*
2     Copyright (C) 2012-2013 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 <boost/test/unit_test.hpp>
21 #include "subtitle_asset.h"
22
23 using std::list;
24 using boost::shared_ptr;
25
26 /* Load a subtitle asset from XML and check that it is read correctly */
27 BOOST_AUTO_TEST_CASE (subtitles1)
28 {
29         libdcp::SubtitleAsset subs ("test/data", "subs1.xml");
30
31         BOOST_CHECK_EQUAL (subs.language(), "French");
32
33         list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_during (libdcp::Time (0, 0, 6, 1, 250), libdcp::Time (0, 0, 6, 2, 250));
34         BOOST_CHECK_EQUAL (s.size(), 1);
35         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
36                                    "Arial",
37                                    false,
38                                    libdcp::Color (255, 255, 255),
39                                    39,
40                                    libdcp::Time (0, 0, 5, 198, 250),
41                                    libdcp::Time (0, 0, 7, 115, 250),
42                                    15,
43                                    libdcp::BOTTOM,
44                                    "My jacket was Idi Amin's",
45                                    libdcp::BORDER,
46                                    libdcp::Color (0, 0, 0),
47                                    libdcp::Time (0, 0, 0, 1, 250),
48                                    libdcp::Time (0, 0, 0, 1, 250)
49                                    ));
50                                                          
51         s = subs.subtitles_during (libdcp::Time (0, 0, 7, 190, 250), libdcp::Time (0, 0, 7, 191, 250));
52         BOOST_CHECK_EQUAL (s.size(), 2);
53         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
54                                    "Arial",
55                                    true,
56                                    libdcp::Color (255, 255, 255),
57                                    39,
58                                    libdcp::Time (0, 0, 7, 177, 250),
59                                    libdcp::Time (0, 0, 11, 31, 250),
60                                    21,
61                                    libdcp::BOTTOM,
62                                    "My corset was H.M. The Queen's",
63                                    libdcp::BORDER,
64                                    libdcp::Color (0, 0, 0),
65                                    libdcp::Time (0, 0, 0, 1, 250),
66                                    libdcp::Time (0, 0, 0, 1, 250)
67                                    ));
68         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
69                                    "Arial",
70                                    false,
71                                    libdcp::Color (255, 255, 255),
72                                    39,
73                                    libdcp::Time (0, 0, 7, 177, 250),
74                                    libdcp::Time (0, 0, 11, 31, 250),
75                                    15,
76                                    libdcp::BOTTOM,
77                                    "My large wonderbra",
78                                    libdcp::BORDER,
79                                    libdcp::Color (0, 0, 0),
80                                    libdcp::Time (0, 0, 0, 1, 250),
81                                    libdcp::Time (0, 0, 0, 1, 250)
82                                    ));
83
84         s = subs.subtitles_during (libdcp::Time (0, 0, 11, 95, 250), libdcp::Time (0, 0, 11, 96, 250));
85         BOOST_CHECK_EQUAL (s.size(), 1);
86         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
87                                    "Arial",
88                                    false,
89                                    libdcp::Color (255, 255, 255),
90                                    39,
91                                    libdcp::Time (0, 0, 11, 94, 250),
92                                    libdcp::Time (0, 0, 13, 63, 250),
93                                    15,
94                                    libdcp::BOTTOM,
95                                    "Once belonged to the Shah",
96                                    libdcp::BORDER,
97                                    libdcp::Color (0, 0, 0),
98                                    libdcp::Time (0, 0, 0, 1, 250),
99                                    libdcp::Time (0, 0, 0, 1, 250)
100                                    ));
101
102         s = subs.subtitles_during (libdcp::Time (0, 0, 14, 42, 250), libdcp::Time (0, 0, 14, 43, 250));
103         BOOST_CHECK_EQUAL (s.size(), 1);
104         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
105                                    "Arial",
106                                    false,
107                                    libdcp::Color (255, 255, 255),
108                                    39,
109                                    libdcp::Time (0, 0, 13, 104, 250),
110                                    libdcp::Time (0, 0, 15, 177, 250),
111                                    15,
112                                    libdcp::BOTTOM,
113                                    "And these are Roy Hattersley's jeans",
114                                    libdcp::BORDER,
115                                    libdcp::Color (0, 0, 0),
116                                    libdcp::Time (0, 0, 0, 1, 250),
117                                    libdcp::Time (0, 0, 0, 1, 250)
118                                    ));
119 }
120
121 /** And similarly for another one */
122 BOOST_AUTO_TEST_CASE (subtitles2)
123 {
124         libdcp::SubtitleAsset subs ("test/data", "subs2.xml");
125
126         list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_during (libdcp::Time (0, 0, 42, 100, 250), libdcp::Time (0, 0, 42, 101, 250));
127         BOOST_CHECK_EQUAL (s.size(), 2);
128         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
129                                    "Arial",
130                                    true,
131                                    libdcp::Color (255, 255, 255),
132                                    42,
133                                    libdcp::Time (0, 0, 41, 62, 250),
134                                    libdcp::Time (0, 0, 43, 52, 250),
135                                    89,
136                                    libdcp::TOP,
137                                    "At afternoon tea with John Peel",
138                                    libdcp::BORDER,
139                                    libdcp::Color (0, 0, 0),
140                                    libdcp::Time (0, 0, 0, 0, 250),
141                                    libdcp::Time (0, 0, 0, 0, 250)
142                                    ));
143         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
144                                    "Arial",
145                                    true,
146                                    libdcp::Color (255, 255, 255),
147                                    42,
148                                    libdcp::Time (0, 0, 41, 62, 250),
149                                    libdcp::Time (0, 0, 43, 52, 250),
150                                    95,
151                                    libdcp::TOP,
152                                    "I enquired if his accent was real",
153                                    libdcp::BORDER,
154                                    libdcp::Color (0, 0, 0),
155                                    libdcp::Time (0, 0, 0, 0, 250),
156                                    libdcp::Time (0, 0, 0, 0, 250)
157                                    ));
158
159         s = subs.subtitles_during (libdcp::Time (0, 0, 50, 50, 250), libdcp::Time (0, 0, 50, 51, 250));
160         BOOST_CHECK_EQUAL (s.size(), 2);
161         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
162                                    "Arial",
163                                    true,
164                                    libdcp::Color (255, 255, 255),
165                                    42,
166                                    libdcp::Time (0, 0, 50, 42, 250),
167                                    libdcp::Time (0, 0, 52, 21, 250),
168                                    89,
169                                    libdcp::TOP,
170                                    "He said \"out of the house",
171                                    libdcp::BORDER,
172                                    libdcp::Color (0, 0, 0),
173                                    libdcp::Time (0, 0, 0, 0, 250),
174                                    libdcp::Time (0, 0, 0, 0, 250)
175                                    ));
176         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
177                                    "Arial",
178                                    true,
179                                    libdcp::Color (255, 255, 255),
180                                    42,
181                                    libdcp::Time (0, 0, 50, 42, 250),
182                                    libdcp::Time (0, 0, 52, 21, 250),
183                                    95,
184                                    libdcp::TOP,
185                                    "I'm incredibly scouse",
186                                    libdcp::BORDER,
187                                    libdcp::Color (0, 0, 0),
188                                    libdcp::Time (0, 0, 0, 0, 250),
189                                    libdcp::Time (0, 0, 0, 0, 250)
190                                    ));
191
192         s = subs.subtitles_during (libdcp::Time (0, 1, 2, 300, 250), libdcp::Time (0, 1, 2, 301, 250));
193         BOOST_CHECK_EQUAL (s.size(), 2);
194         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
195                                    "Arial",
196                                    true,
197                                    libdcp::Color (255, 255, 255),
198                                    42,
199                                    libdcp::Time (0, 1, 2, 208, 250),
200                                    libdcp::Time (0, 1, 4, 10, 250),
201                                    89,
202                                    libdcp::TOP,
203                                    "At home it depends how I feel.\"",
204                                    libdcp::BORDER,
205                                    libdcp::Color (0, 0, 0),
206                                    libdcp::Time (0, 0, 0, 0, 250),
207                                    libdcp::Time (0, 0, 0, 0, 250)
208                                    ));
209         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
210                                    "Arial",
211                                    true,
212                                    libdcp::Color (255, 255, 255),
213                                    42,
214                                    libdcp::Time (0, 1, 2, 208, 250),
215                                    libdcp::Time (0, 1, 4, 10, 250),
216                                    95,
217                                    libdcp::TOP,
218                                    "I spent a long weekend in Brighton",
219                                    libdcp::BORDER,
220                                    libdcp::Color (0, 0, 0),
221                                    libdcp::Time (0, 0, 0, 0, 250),
222                                    libdcp::Time (0, 0, 0, 0, 250)
223                                    ));
224
225         s = subs.subtitles_during (libdcp::Time (0, 1, 15, 50, 250), libdcp::Time (0, 1, 15, 51, 250));
226         BOOST_CHECK_EQUAL (s.size(), 2);
227         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
228                                    "Arial",
229                                    true,
230                                    libdcp::Color (255, 255, 255),
231                                    42,
232                                    libdcp::Time (0, 1, 15, 42, 250),
233                                    libdcp::Time (0, 1, 16, 42, 250),
234                                    89,
235                                    libdcp::TOP,
236                                    "With the legendary Miss Enid Blyton",
237                                    libdcp::BORDER,
238                                    libdcp::Color (0, 0, 0),
239                                    libdcp::Time (0, 0, 0, 0, 250),
240                                    libdcp::Time (0, 0, 0, 0, 250)
241                                    ));
242         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
243                                    "Arial",
244                                    true,
245                                    libdcp::Color (255, 255, 255),
246                                    42,
247                                    libdcp::Time (0, 1, 15, 42, 250),
248                                    libdcp::Time (0, 1, 16, 42, 250),
249                                    95,
250                                    libdcp::TOP,
251                                    "She said \"you be Noddy",
252                                    libdcp::BORDER,
253                                    libdcp::Color (0, 0, 0),
254                                    libdcp::Time (0, 0, 0, 0, 250),
255                                    libdcp::Time (0, 0, 0, 0, 250)
256                                    ));
257
258         s = subs.subtitles_during (libdcp::Time (0, 1, 27, 200, 250), libdcp::Time (0, 1, 27, 201, 250));
259         BOOST_CHECK_EQUAL (s.size(), 2);
260         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
261                                    "Arial",
262                                    true,
263                                    libdcp::Color (255, 255, 255),
264                                    42,
265                                    libdcp::Time (0, 1, 27, 115, 250),
266                                    libdcp::Time (0, 1, 28, 208, 250),
267                                    89,
268                                    libdcp::TOP,
269                                    "That curious creature the Sphinx",
270                                    libdcp::BORDER,
271                                    libdcp::Color (0, 0, 0),
272                                    libdcp::Time (0, 0, 0, 0, 250),
273                                    libdcp::Time (0, 0, 0, 0, 250)
274                                    ));
275         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
276                                    "Arial",
277                                    true,
278                                    libdcp::Color (255, 255, 255),
279                                    42,
280                                    libdcp::Time (0, 1, 27, 115, 250),
281                                    libdcp::Time (0, 1, 28, 208, 250),
282                                    95,
283                                    libdcp::TOP,
284                                    "Is smarter than anyone thinks",
285                                    libdcp::BORDER,
286                                    libdcp::Color (0, 0, 0),
287                                    libdcp::Time (0, 0, 0, 0, 250),
288                                    libdcp::Time (0, 0, 0, 0, 250)
289                                    ));
290
291         s = subs.subtitles_during (libdcp::Time (0, 1, 42, 300, 250), libdcp::Time (0, 1, 42, 301, 250));
292         BOOST_CHECK_EQUAL (s.size(), 2);
293         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
294                                    "Arial",
295                                    false,
296                                    libdcp::Color (255, 255, 255),
297                                    42,
298                                    libdcp::Time (0, 1, 42, 229, 250),
299                                    libdcp::Time (0, 1, 45, 62, 250),
300                                    89,
301                                    libdcp::TOP,
302                                    "It sits there and smirks",
303                                    libdcp::BORDER,
304                                    libdcp::Color (0, 0, 0),
305                                    libdcp::Time (0, 0, 0, 0, 250),
306                                    libdcp::Time (0, 0, 0, 0, 250)
307                                    ));
308         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
309                                    "Arial",
310                                    false,
311                                    libdcp::Color (255, 255, 255),
312                                    42,
313                                    libdcp::Time (0, 1, 42, 229, 250),
314                                    libdcp::Time (0, 1, 45, 62, 250),
315                                    95,
316                                    libdcp::TOP,
317                                    "And you don't think it works",
318                                    libdcp::BORDER,
319                                    libdcp::Color (0, 0, 0),
320                                    libdcp::Time (0, 0, 0, 0, 250),
321                                    libdcp::Time (0, 0, 0, 0, 250)
322                                    ));
323
324         s = subs.subtitles_during (libdcp::Time (0, 1, 45, 200, 250), libdcp::Time (0, 1, 45, 201, 250));
325         BOOST_CHECK_EQUAL (s.size(), 2);
326         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
327                                    "Arial",
328                                    false,
329                                    libdcp::Color (255, 255, 255),
330                                    42,
331                                    libdcp::Time (0, 1, 45, 146, 250),
332                                    libdcp::Time (0, 1, 47, 94, 250),
333                                    89,
334                                    libdcp::TOP,
335                                    "Then when you're not looking, it winks.",
336                                    libdcp::BORDER,
337                                    libdcp::Color (0, 0, 0),
338                                    libdcp::Time (0, 0, 0, 0, 250),
339                                    libdcp::Time (0, 0, 0, 0, 250)
340                                    ));
341         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
342                                    "Arial",
343                                    false,
344                                    libdcp::Color (255, 255, 255),
345                                    42,
346                                    libdcp::Time (0, 1, 45, 146, 250),
347                                    libdcp::Time (0, 1, 47, 94, 250),
348                                    95,
349                                    libdcp::TOP,
350                                    "When it snows you will find Sister Sledge",
351                                    libdcp::BORDER,
352                                    libdcp::Color (0, 0, 0),
353                                    libdcp::Time (0, 0, 0, 0, 250),
354                                    libdcp::Time (0, 0, 0, 0, 250)
355                                    ));
356
357         s = subs.subtitles_during (libdcp::Time (0, 1, 47, 249, 250), libdcp::Time (0, 1, 47, 250, 250));
358         BOOST_CHECK_EQUAL (s.size(), 2);
359         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
360                                    "Arial",
361                                    false,
362                                    libdcp::Color (255, 255, 255),
363                                    42,
364                                    libdcp::Time (0, 1, 47, 146, 250),
365                                    libdcp::Time (0, 1, 48, 167, 250),
366                                    89,
367                                    libdcp::TOP,
368                                    "Out mooning, at night, on the ledge",
369                                    libdcp::BORDER,
370                                    libdcp::Color (0, 0, 0),
371                                    libdcp::Time (0, 0, 0, 0, 250),
372                                    libdcp::Time (0, 0, 0, 0, 250)
373                                    ));
374         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
375                                    "Arial",
376                                    false,
377                                    libdcp::Color (255, 255, 255),
378                                    42,
379                                    libdcp::Time (0, 1, 47, 146, 250),
380                                    libdcp::Time (0, 1, 48, 167, 250),
381                                    95,
382                                    libdcp::TOP,
383                                    "One storey down",
384                                    libdcp::BORDER,
385                                    libdcp::Color (0, 0, 0),
386                                    libdcp::Time (0, 0, 0, 0, 250),
387                                    libdcp::Time (0, 0, 0, 0, 250)
388                                    ));
389
390         s = subs.subtitles_during (libdcp::Time (0, 2, 6, 210, 250), libdcp::Time (0, 2, 6, 211, 250));
391         BOOST_CHECK_EQUAL (s.size(), 2);
392         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
393                                    "Arial",
394                                    true,
395                                    libdcp::Color (255, 255, 255),
396                                    42,
397                                    libdcp::Time (0, 2, 5, 208, 250),
398                                    libdcp::Time (0, 2, 7, 31, 250),
399                                    89,
400                                    libdcp::TOP,
401                                    "HELLO",
402                                    libdcp::BORDER,
403                                    libdcp::Color (0, 0, 0),
404                                    libdcp::Time (0, 0, 0, 0, 250),
405                                    libdcp::Time (0, 0, 0, 0, 250)
406                                    ));
407         BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
408                                    "Arial",
409                                    true,
410                                    libdcp::Color (255, 255, 255),
411                                    42,
412                                    libdcp::Time (0, 2, 5, 208, 250),
413                                    libdcp::Time (0, 2, 7, 31, 250),
414                                    95,
415                                    libdcp::TOP,
416                                    "WORLD",
417                                    libdcp::BORDER,
418                                    libdcp::Color (0, 0, 0),
419                                    libdcp::Time (0, 0, 0, 0, 250),
420                                    libdcp::Time (0, 0, 0, 0, 250)
421                                    ));
422 }
423
424 /* A very simple SMPTE one */
425 BOOST_AUTO_TEST_CASE (subtitles3)
426 {
427         libdcp::SubtitleAsset subs ("test/data", "subs3.xml");
428
429         list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_during (libdcp::Time (0, 0, 0, 0, 25), libdcp::Time (0, 0, 7, 0, 25));
430
431         BOOST_REQUIRE_EQUAL (s.size(), 1);
432         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
433                                    "",
434                                    false,
435                                    libdcp::Color (255, 255, 255),
436                                    42,
437                                    libdcp::Time (0, 0, 4, 21, 25),
438                                    libdcp::Time (0, 0, 6, 5, 25),
439                                    8,
440                                    libdcp::BOTTOM,
441                                    "Hello world",
442                                    libdcp::BORDER,
443                                    libdcp::Color (0, 0, 0),
444                                    libdcp::Time (0, 0, 0, 0, 25),
445                                    libdcp::Time (0, 0, 0, 0, 25)
446                                    ));
447 }
448
449 /* <Font italic="yes"> in the middle of a string */
450 BOOST_AUTO_TEST_CASE (subtitles4)
451 {
452         libdcp::SubtitleAsset subs ("test/data", "subs4.xml");
453
454         list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_during (libdcp::Time (0, 0, 0, 0, 25), libdcp::Time (0, 0, 7, 0, 25));
455
456         BOOST_REQUIRE_EQUAL (s.size(), 1);
457         BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
458                                    "",
459                                    false,
460                                    libdcp::Color (255, 255, 255),
461                                    42,
462                                    libdcp::Time (0, 0, 4, 21, 25),
463                                    libdcp::Time (0, 0, 6, 5, 25),
464                                    8,
465                                    libdcp::BOTTOM,
466                                    "Hello <i>there</i> world",
467                                    libdcp::BORDER,
468                                    libdcp::Color (0, 0, 0),
469                                    libdcp::Time (0, 0, 0, 0, 25),
470                                    libdcp::Time (0, 0, 0, 0, 25)
471                                    ));
472 }