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