#include "config.h"
#include "constants.h"
#include "cross.h"
-#include "crypto.h"
#include "dcp_content_type.h"
#include "dcpomatic_log.h"
#include "digester.h"
#include "ratio.h"
#include "rect.h"
#include "render_text.h"
-#include "scope_guard.h"
#include "string_text.h"
#include "text_decoder.h"
#include "util.h"
+#include "variant.h"
#include "video_content.h"
#include <dcp/atmos_asset.h>
#include <dcp/decrypted_kdm.h>
+#include <dcp/file.h>
+#include <dcp/filesystem.h>
#include <dcp/locale_convert.h>
+#include <dcp/mpeg2_picture_asset.h>
#include <dcp/picture_asset.h>
#include <dcp/raw_convert.h>
+#include <dcp/scope_guard.h>
#include <dcp/sound_asset.h>
#include <dcp/subtitle_asset.h>
#include <dcp/util.h>
#include <dbghelp.h>
#endif
#include <signal.h>
+#include <climits>
#include <iomanip>
#include <iostream>
#include <fstream>
-#include <climits>
+#include <numeric>
#include <stdexcept>
#ifdef DCPOMATIC_POSIX
#include <execinfo.h>
using std::bad_alloc;
using std::cout;
+using std::dynamic_pointer_cast;
using std::endl;
using std::istream;
using std::list;
using std::wstring;
using boost::thread;
using boost::optional;
-using boost::lexical_cast;
-using boost::bad_lexical_cast;
-using boost::scoped_array;
using dcp::Size;
using dcp::raw_convert;
using dcp::locale_convert;
{
char addr2line_cmd[512] = { 0 };
sprintf (addr2line_cmd, "addr2line -f -p -e %.256s %p > %s", program_name.c_str(), addr, backtrace_file.string().c_str());
+ std::cout << addr2line_cmd << "\n";
return system(addr2line_cmd);
}
}
-static
void
capture_ffmpeg_logs()
{
SetUnhandledExceptionFilter(exception_handler);
#endif
+#ifdef DCPOMATIC_GROK
+ /* This makes grok support work with CUDA 12.2 */
+ setenv("CUDA_MODULE_LOADING", "EAGER", 1);
+#endif
+
#ifdef DCPOMATIC_HAVE_AVREGISTER
LIBDCP_DISABLE_WARNINGS
av_register_all ();
#ifdef DCPOMATIC_WINDOWS
putenv ("PANGOCAIRO_BACKEND=fontconfig");
- putenv (String::compose("FONTCONFIG_PATH=%1", resources_path().string()).c_str());
+ if (dcp::filesystem::exists(resources_path() / "fonts.conf")) {
+ /* The actual application after installation */
+ putenv(String::compose("FONTCONFIG_PATH=%1", resources_path().string()).c_str());
+ } else {
+ /* The place where fonts.conf is during tests */
+ putenv("FONTCONFIG_PATH=build\\fonts");
+ }
#endif
#ifdef DCPOMATIC_OSX
#if defined(DCPOMATIC_WINDOWS) || defined(DCPOMATIC_OSX)
/* Render something to fontconfig to create its cache */
- list<StringText> subs;
+ vector<StringText> subs;
dcp::SubtitleString ss(
optional<string>(), false, false, false, dcp::Colour(), 42, 1, dcp::Time(), dcp::Time(), 0, dcp::HAlign::CENTER, 0, dcp::VAlign::CENTER, 0, dcp::Direction::LTR,
- "Hello dolly", dcp::Effect::NONE, dcp::Colour(), dcp::Time(), dcp::Time(), 0
+ "Hello dolly", dcp::Effect::NONE, dcp::Colour(), dcp::Time(), dcp::Time(), 0, std::vector<dcp::Ruby>()
);
subs.push_back(StringText(ss, 0, make_shared<dcpomatic::Font>("foo"), dcp::SubtitleStandard::SMPTE_2014));
render_text (subs, dcp::Size(640, 480), DCPTime(), 24);
boost::filesystem::path
mo_path ()
{
- return "DCP-o-matic 2.app/Contents/Resources";
+ return variant::dcpomatic_app() + "/Contents/Resources";
}
#endif
throw OpenFileError (files[i].string(), errno, OpenFileError::READ);
}
- boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i]));
+ auto this_time = min(to_do, dcp::filesystem::file_size(files[i]));
f.checked_read(p, this_time);
p += this_time;
to_do -= this_time;
throw OpenFileError (files[i].string(), errno, OpenFileError::READ);
}
- boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i]));
+ auto this_time = min(to_do, dcp::filesystem::file_size(files[i]));
f.seek(-this_time, SEEK_END);
f.checked_read(p, this_time);
p += this_time;
string
simple_digest (vector<boost::filesystem::path> paths)
{
- return digest_head_tail(paths, 1000000) + raw_convert<string>(boost::filesystem::file_size(paths.front()));
+ DCP_ASSERT(!paths.empty());
+ return digest_head_tail(paths, 1000000) + raw_convert<string>(dcp::filesystem::file_size(paths.front()));
}
bool
valid_image_file (boost::filesystem::path f)
{
- if (boost::starts_with (f.leaf().string(), "._")) {
+ if (boost::starts_with(f.filename().string(), "._")) {
return false;
}
bool
valid_sound_file (boost::filesystem::path f)
{
- if (boost::starts_with (f.leaf().string(), "._")) {
+ if (boost::starts_with(f.filename().string(), "._")) {
return false;
}
values['r'] = raw_convert<string>(reel_index + 1);
values['n'] = raw_convert<string>(reel_count);
if (summary) {
- values['c'] = careful_string_filter(summary.get());
+ values['c'] = summary.get();
}
- return Config::instance()->dcp_asset_filename_format().get(values, "_" + asset->id() + extension);
+ return careful_string_filter(Config::instance()->dcp_asset_filename_format().get(values, "_" + asset->id() + extension));
}
string
-video_asset_filename (shared_ptr<dcp::PictureAsset> asset, int reel_index, int reel_count, optional<string> summary)
+video_asset_filename(shared_ptr<dcp::PictureAsset> asset, int reel_index, int reel_count, optional<string> summary)
{
- return asset_filename(asset, "j2c", reel_index, reel_count, summary, ".mxf");
+ string type = dynamic_pointer_cast<dcp::MPEG2PictureAsset>(asset) ? "mpeg2" : "j2c";
+ return asset_filename(asset, type, reel_index, reel_count, summary, ".mxf");
}
/* Then remove anything that's not in a very limited character set */
wstring out;
- wstring const allowed = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_%.+";
+ wstring const allowed = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.+";
for (int i = 0; i < transliterated_more.length(); ++i) {
wchar_t c = transliterated_more[i];
if (allowed.find(c) != string::npos) {
case dcp::Channel::BSR:
++non_lfe;
break;
+ case dcp::Channel::LC:
+ case dcp::Channel::RC:
case dcp::Channel::HI:
case dcp::Channel::VI:
case dcp::Channel::MOTION_DATA:
return mapped;
}
-Eyes
-increment_eyes (Eyes e)
-{
- if (e == Eyes::LEFT) {
- return Eyes::RIGHT;
- }
-
- return Eyes::LEFT;
-}
-
size_t
utf8_strlen (string s)
std::vector<uint8_t> buffer(chunk);
- boost::uintmax_t const total = boost::filesystem::file_size (from);
+ auto const total = dcp::filesystem::file_size(from);
boost::uintmax_t remaining = total;
while (remaining) {
}
}
if (!on_chain) {
- throw KDMError (_("This KDM was not made for DCP-o-matic's decryption certificate."), e.what());
+ throw KDMError(variant::insert_dcpomatic(_("This KDM was not made for %1's decryption certificate.")), e.what());
} else if (kdm_subject_name != dc->leaf().subject()) {
- throw KDMError (_("This KDM was made for DCP-o-matic but not for its leaf certificate."), e.what());
+ throw KDMError(variant::insert_dcpomatic(_("This KDM was made for %1 but not for its leaf certificate.")), e.what());
} else {
throw;
}
boost::filesystem::path liberation_normal;
try {
liberation_normal = resources_path() / "LiberationSans-Regular.ttf";
- if (!boost::filesystem::exists (liberation_normal)) {
+ if (!dcp::filesystem::exists(liberation_normal)) {
/* Hack for unit tests */
liberation_normal = resources_path() / "fonts" / "LiberationSans-Regular.ttf";
}
}
- if (!boost::filesystem::exists(liberation_normal)) {
+ if (!dcp::filesystem::exists(liberation_normal)) {
liberation_normal = "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf";
}
- if (!boost::filesystem::exists(liberation_normal)) {
+ if (!dcp::filesystem::exists(liberation_normal)) {
liberation_normal = "/usr/share/fonts/liberation-sans/LiberationSans-Regular.ttf";
}
bool
contains_assetmap(boost::filesystem::path dir)
{
- return boost::filesystem::is_regular_file(dir / "ASSETMAP") || boost::filesystem::is_regular_file(dir / "ASSETMAP.xml");
+ return dcp::filesystem::is_regular_file(dir / "ASSETMAP") || dcp::filesystem::is_regular_file(dir / "ASSETMAP.xml");
}
icu::Locale locale;
UErrorCode status = U_ZERO_ERROR;
auto iter = icu::BreakIterator::createLineInstance(locale, status);
- ScopeGuard sg = [iter]() { delete iter; };
+ dcp::ScopeGuard sg = [iter]() { delete iter; };
if (U_FAILURE(status)) {
return input;
}
return output;
}
+
+#ifdef DCPOMATIC_GROK
+void
+setup_grok_library_path()
+{
+ static std::string old_path;
+ if (old_path.empty()) {
+ auto const old = getenv("LD_LIRARY_PATH");
+ if (old) {
+ old_path = old;
+ }
+ }
+ auto const grok = Config::instance()->grok();
+ if (!grok || grok->binary_location.empty()) {
+ setenv("LD_LIRARY_PATH", old_path.c_str(), 1);
+ return;
+ }
+
+ std::string new_path = old_path;
+ if (!new_path.empty()) {
+ new_path += ":";
+ }
+ new_path += grok->binary_location.string();
+
+ setenv("LD_LIBRARY_PATH", new_path.c_str(), 1);
+}
+#endif
+
+
+string
+screen_names_to_string(vector<string> names)
+{
+ if (names.empty()) {
+ return {};
+ }
+
+ auto number = [](string const& s) {
+ return s.find_first_not_of("0123456789") == string::npos;
+ };
+
+ if (std::find_if(names.begin(), names.end(), [number](string const& s) { return !number(s); }) == names.end()) {
+ std::sort(names.begin(), names.end(), [](string const& a, string const& b) {
+ return dcp::raw_convert<int>(a) < dcp::raw_convert<int>(b);
+ });
+ } else {
+ std::sort(names.begin(), names.end());
+ }
+
+ string result;
+ for (auto const& name: names) {
+ result += name + ", ";
+ }
+
+ return result.substr(0, result.length() - 2);
+}
+
+
+string
+report_problem()
+{
+ return String::compose(_("Please report this problem by using Help -> Report a problem or via email to %1"), variant::report_problem_email());
+}
+
+
+string
+join_strings(vector<string> const& in, string const& separator)
+{
+ if (in.empty()) {
+ return {};
+ }
+
+ return std::accumulate(std::next(in.begin()), in.end(), in.front(), [separator](string a, string b) {
+ return a + separator + b;
+ });
+}
+