+ return (ext == N_(".tif") || ext == N_(".tiff") || ext == N_(".jpg") || ext == N_(".jpeg") || ext == N_(".png") || ext == N_(".bmp"));
+}
+
+/** @return A pair containing CPU model name and the number of processors */
+pair<string, int>
+cpu_info ()
+{
+ pair<string, int> info;
+ info.second = 0;
+
+#ifdef DVDOMATIC_POSIX
+ ifstream f (N_("/proc/cpuinfo"));
+ while (f.good ()) {
+ string l;
+ getline (f, l);
+ if (boost::algorithm::starts_with (l, N_("model name"))) {
+ string::size_type const c = l.find (':');
+ if (c != string::npos) {
+ info.first = l.substr (c + 2);
+ }
+ } else if (boost::algorithm::starts_with (l, N_("processor"))) {
+ ++info.second;
+ }
+ }
+#endif
+
+ return info;
+}
+
+string
+audio_channel_name (int c)
+{
+ assert (MAX_AUDIO_CHANNELS == 6);
+
+ /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency
+ enhancement channel (sub-woofer)./
+ */
+ string const channels[] = {
+ "Left",
+ "Right",
+ "Centre",
+ "Lfe (sub)",
+ "Left surround",
+ "Right surround",
+ };
+
+ return channels[c];
+}
+
+AudioMapping::AudioMapping (int c)
+ : _source_channels (c)
+{
+
+}
+
+optional<libdcp::Channel>
+AudioMapping::source_to_dcp (int c) const
+{
+ if (c >= _source_channels) {
+ return optional<libdcp::Channel> ();
+ }
+
+ if (_source_channels == 1) {
+ /* mono sources to centre */
+ return libdcp::CENTRE;
+ }
+
+ return static_cast<libdcp::Channel> (c);
+}
+
+optional<int>
+AudioMapping::dcp_to_source (libdcp::Channel c) const
+{
+ if (_source_channels == 1) {
+ if (c == libdcp::CENTRE) {
+ return 0;
+ } else {
+ return optional<int> ();
+ }
+ }
+
+ if (static_cast<int> (c) >= _source_channels) {
+ return optional<int> ();
+ }
+
+ return static_cast<int> (c);
+}
+
+int
+AudioMapping::dcp_channels () const
+{
+ if (_source_channels == 1) {
+ /* The source is mono, so to put the mono channel into
+ the centre we need to generate a 5.1 soundtrack.
+ */
+ return 6;
+ }
+
+ return _source_channels;
+}
+
+FrameRateConversion::FrameRateConversion (float source, int dcp)
+ : skip (false)
+ , repeat (false)
+ , change_speed (false)
+{
+ if (fabs (source / 2.0 - dcp) < (fabs (source - dcp))) {
+ skip = true;
+ } else if (fabs (source * 2 - dcp) < fabs (source - dcp)) {
+ repeat = true;
+ }
+
+ change_speed = !about_equal (source * factor(), dcp);
+
+ if (!skip && !repeat && !change_speed) {
+ description = _("DCP and source have the same rate.\n");
+ } else {
+ if (skip) {
+ description = _("DCP will use every other frame of the source.\n");
+ } else if (repeat) {
+ description = _("Each source frame will be doubled in the DCP.\n");
+ }
+
+ if (change_speed) {
+ float const pc = dcp * 100 / (source * factor());
+ description += String::compose (_("DCP will run at %1%% of the source speed."), pc);
+ }
+ }