Move things round a bit.
[dcpomatic.git] / test / short.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 <fstream>
21 #include <iostream>
22 #include <boost/filesystem.hpp>
23 #include <boost/algorithm/string/predicate.hpp>
24 #include "format.h"
25 #include "film.h"
26 #include "filter.h"
27 #include "job_manager.h"
28 #include "util.h"
29 #include "exceptions.h"
30 #include "dvd.h"
31 #include "delay_line.h"
32 #define BOOST_TEST_DYN_LINK
33 #define BOOST_TEST_MODULE dvdomatic_test
34 #include <boost/test/unit_test.hpp>
35
36 using namespace std;
37 using namespace boost;
38
39 BOOST_AUTO_TEST_CASE (film_metadata_test)
40 {
41         dvdomatic_setup ();
42         
43         string const test_film = "build/test/film";
44         
45         if (boost::filesystem::exists (test_film)) {
46                 boost::filesystem::remove_all (test_film);
47         }
48
49         BOOST_CHECK_THROW (new Film ("build/test/film", true), OpenFileError);
50         
51         Film f (test_film, false);
52         BOOST_CHECK (f.format() == 0);
53         BOOST_CHECK (f.dcp_content_type() == 0);
54         BOOST_CHECK (f.filters ().empty());
55
56         f.set_name ("fred");
57         BOOST_CHECK_THROW (f.set_content ("jim"), OpenFileError);
58         f.set_dcp_content_type (DCPContentType::from_pretty_name ("Short"));
59         f.set_format (Format::from_nickname ("Flat"));
60         f.set_left_crop (1);
61         f.set_right_crop (2);
62         f.set_top_crop (3);
63         f.set_bottom_crop (4);
64         vector<Filter const *> f_filters;
65         f_filters.push_back (Filter::from_id ("pphb"));
66         f_filters.push_back (Filter::from_id ("unsharp"));
67         f.set_filters (f_filters);
68         f.set_dcp_frames (42);
69         f.set_dcp_ab (true);
70         f.write_metadata ();
71
72         stringstream s;
73         s << "diff -u test/metadata.ref " << test_film << "/metadata";
74         BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0);
75
76         Film g (test_film, true);
77
78         BOOST_CHECK_EQUAL (g.name(), "fred");
79         BOOST_CHECK_EQUAL (g.dcp_content_type(), DCPContentType::from_pretty_name ("Short"));
80         BOOST_CHECK_EQUAL (g.format(), Format::from_nickname ("Flat"));
81         BOOST_CHECK_EQUAL (g.left_crop(), 1);
82         BOOST_CHECK_EQUAL (g.right_crop(), 2);
83         BOOST_CHECK_EQUAL (g.top_crop(), 3);
84         BOOST_CHECK_EQUAL (g.bottom_crop(), 4);
85         vector<Filter const *> g_filters = g.filters ();
86         BOOST_CHECK_EQUAL (g_filters.size(), 2);
87         BOOST_CHECK_EQUAL (g_filters.front(), Filter::from_id ("pphb"));
88         BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp"));
89         BOOST_CHECK_EQUAL (g.dcp_frames(), 42);
90         BOOST_CHECK_EQUAL (g.dcp_ab(), true);
91         
92         g.write_metadata ();
93         BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0);
94 }
95
96 BOOST_AUTO_TEST_CASE (format_test)
97 {
98         Format::setup_formats ();
99         
100         Format const * f = Format::from_nickname ("Flat");
101         BOOST_CHECK (f);
102         BOOST_CHECK_EQUAL (f->ratio_as_integer(), 185);
103         
104         f = Format::from_nickname ("Scope");
105         BOOST_CHECK (f);
106         BOOST_CHECK_EQUAL (f->ratio_as_integer(), 239);
107 }
108
109 BOOST_AUTO_TEST_CASE (util_test)
110 {
111         string t = "Hello this is a string \"with quotes\" and indeed without them";
112         vector<string> b = split_at_spaces_considering_quotes (t);
113         vector<string>::iterator i = b.begin ();
114         BOOST_CHECK_EQUAL (*i++, "Hello");
115         BOOST_CHECK_EQUAL (*i++, "this");
116         BOOST_CHECK_EQUAL (*i++, "is");
117         BOOST_CHECK_EQUAL (*i++, "a");
118         BOOST_CHECK_EQUAL (*i++, "string");
119         BOOST_CHECK_EQUAL (*i++, "with quotes");
120         BOOST_CHECK_EQUAL (*i++, "and");
121         BOOST_CHECK_EQUAL (*i++, "indeed");
122         BOOST_CHECK_EQUAL (*i++, "without");
123         BOOST_CHECK_EQUAL (*i++, "them");
124 }
125
126 BOOST_AUTO_TEST_CASE (dvd_test)
127 {
128         vector<uint64_t> const t = dvd_titles ("test/dvd");
129         BOOST_CHECK_EQUAL (t.size(), 4);
130         BOOST_CHECK_EQUAL (t[1], 0);
131         BOOST_CHECK_EQUAL (t[2], 14);
132         BOOST_CHECK_EQUAL (t[3], 7);
133 }
134
135 void
136 do_positive_delay_line_test (int delay_length, int block_length)
137 {
138         DelayLine d (delay_length);
139         uint8_t data[block_length];
140
141         int in = 0;
142         int out = 0;
143         int returned = 0;
144         int zeros = 0;
145         
146         for (int i = 0; i < 64; ++i) {
147                 for (int j = 0; j < block_length; ++j) {
148                         data[j] = in;
149                         ++in;
150                 }
151
152                 int const a = d.feed (data, block_length);
153                 returned += a;
154
155                 for (int j = 0; j < a; ++j) {
156                         if (zeros < delay_length) {
157                                 BOOST_CHECK_EQUAL (data[j], 0);
158                                 ++zeros;
159                         } else {
160                                 BOOST_CHECK_EQUAL (data[j], out & 0xff);
161                                 ++out;
162                         }
163                 }
164         }
165
166         BOOST_CHECK_EQUAL (returned, 64 * block_length);
167 }
168
169 void
170 do_negative_delay_line_test (int delay_length, int block_length)
171 {
172         DelayLine d (delay_length);
173         uint8_t data[block_length];
174
175         int in = 0;
176         int out = -delay_length;
177         int returned = 0;
178         
179         for (int i = 0; i < 256; ++i) {
180                 for (int j = 0; j < block_length; ++j) {
181                         data[j] = in;
182                         ++in;
183                 }
184
185                 int const a = d.feed (data, block_length);
186                 returned += a;
187
188                 for (int j = 0; j < a; ++j) {
189                         BOOST_CHECK_EQUAL (data[j], out & 0xff);
190                         ++out;
191                 }
192         }
193
194         uint8_t remainder[-delay_length];
195         d.get_remaining (remainder);
196         returned += -delay_length;
197
198         for (int i = 0; i < -delay_length; ++i) {
199                 BOOST_CHECK_EQUAL (remainder[i], 0);
200                 ++out;
201         }
202
203         BOOST_CHECK_EQUAL (returned, 256 * block_length);
204         
205 }
206
207 BOOST_AUTO_TEST_CASE (delay_line_test)
208 {
209         do_positive_delay_line_test (64, 128);
210         do_positive_delay_line_test (128, 64);
211         do_positive_delay_line_test (3, 512);
212         do_positive_delay_line_test (512, 3);
213
214         do_positive_delay_line_test (0, 64);
215
216         do_negative_delay_line_test (-64, 128);
217         do_negative_delay_line_test (-128, 64);
218         do_negative_delay_line_test (-3, 512);
219         do_negative_delay_line_test (-512, 3);
220 }