#include <magick/MagickCore.h>
#include <magick/version.h>
#include <libdcp/version.h>
+#include <libdcp/util.h>
+#include <libdcp/signer_chain.h>
+#include <libdcp/signer.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include "sound_processor.h"
#include "config.h"
#include "ratio.h"
+#include "job.h"
+#include "cross.h"
#ifdef DCPOMATIC_WINDOWS
#include "stack.hpp"
#endif
#endif
avfilter_register_all ();
+
+#ifdef DCPOMATIC_OSX
+ /* Add our lib directory to the libltdl search path so that
+ xmlsec can find xmlsec1-openssl.
+ */
+ boost::filesystem::path lib = app_contents ();
+ lib /= "lib";
+ setenv ("LTDL_LIBRARY_PATH", lib.c_str (), 1);
+#endif
+
+ libdcp::init ();
Ratio::setup_ratios ();
DCPContentType::setup_dcp_content_types ();
return s.str ();
}
+/** @param job Optional job for which to report progress */
string
-md5_digest_directory (boost::filesystem::path directory)
+md5_digest_directory (boost::filesystem::path directory, shared_ptr<Job> job)
{
int const buffer_size = 64 * 1024;
char buffer[buffer_size];
MD5_CTX md5_context;
MD5_Init (&md5_context);
-
+
+ int files = 0;
+ if (job) {
+ for (boost::filesystem::directory_iterator i(directory); i != boost::filesystem::directory_iterator(); ++i) {
+ ++files;
+ }
+ }
+
+ int j = 0;
for (boost::filesystem::directory_iterator i(directory); i != boost::filesystem::directory_iterator(); ++i) {
ifstream f (i->path().string().c_str(), std::ios::binary);
if (!f.good ()) {
MD5_Update (&md5_context, buffer, t);
bytes -= t;
}
+
+ if (job) {
+ job->set_progress (float (j) / files);
+ ++j;
+ }
}
unsigned char digest[MD5_DIGEST_LENGTH];
assert (MAX_AUDIO_CHANNELS == 6);
/* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency
- enhancement channel (sub-woofer)./
+ enhancement channel (sub-woofer).
*/
string const channels[] = {
_("Left"),
FrameRateConversion::FrameRateConversion (float source, int dcp)
: skip (false)
- , repeat (false)
+ , repeat (1)
, change_speed (false)
{
- if (fabs (source / 2.0 - dcp) < (fabs (source - dcp))) {
+ if (source > (dcp * 2)) {
skip = true;
- } else if (fabs (source * 2 - dcp) < fabs (source - dcp)) {
- repeat = true;
+ }
+
+ if (source < dcp) {
+ repeat = floor (dcp / source);
}
change_speed = !about_equal (source * factor(), dcp);
- if (!skip && !repeat && !change_speed) {
+ if (!skip && repeat == 1 && !change_speed) {
description = _("Content and DCP have the same rate.\n");
} else {
if (skip) {
description = _("DCP will use every other frame of the content.\n");
- } else if (repeat) {
+ } else if (repeat == 2) {
description = _("Each content frame will be doubled in the DCP.\n");
+ } else if (repeat > 2) {
+ description = String::compose (_("Each content frame will be repeated %1 more times in the DCP.\n"), repeat - 1);
}
if (change_speed) {
setlocale (LC_NUMERIC, _old);
free (_old);
}
+
+bool
+valid_image_file (boost::filesystem::path f)
+{
+ string ext = f.extension().string();
+ transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+ return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp" || ext == ".tga");
+}
+
+string
+tidy_for_filename (string f)
+{
+ string t;
+ for (size_t i = 0; i < f.length(); ++i) {
+ if (isalnum (f[i]) || f[i] == '_' || f[i] == '-') {
+ t += f[i];
+ } else {
+ t += '_';
+ }
+ }
+
+ return t;
+}
+
+shared_ptr<const libdcp::Signer>
+make_signer ()
+{
+ boost::filesystem::path const sd = Config::instance()->signer_chain_directory ();
+
+ /* Remake the chain if any of it is missing */
+
+ list<boost::filesystem::path> files;
+ files.push_back ("ca.self-signed.pem");
+ files.push_back ("intermediate.signed.pem");
+ files.push_back ("leaf.signed.pem");
+ files.push_back ("leaf.key");
+
+ list<boost::filesystem::path>::const_iterator i = files.begin();
+ while (i != files.end()) {
+ boost::filesystem::path p (sd);
+ p /= *i;
+ if (!boost::filesystem::exists (p)) {
+ boost::filesystem::remove_all (sd);
+ boost::filesystem::create_directories (sd);
+ libdcp::make_signer_chain (sd, openssl_path ());
+ break;
+ }
+
+ ++i;
+ }
+
+ libdcp::CertificateChain chain;
+
+ {
+ boost::filesystem::path p (sd);
+ p /= "ca.self-signed.pem";
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
+ }
+
+ {
+ boost::filesystem::path p (sd);
+ p /= "intermediate.signed.pem";
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
+ }
+
+ {
+ boost::filesystem::path p (sd);
+ p /= "leaf.signed.pem";
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
+ }
+
+ boost::filesystem::path signer_key (sd);
+ signer_key /= "leaf.key";
+
+ return shared_ptr<const libdcp::Signer> (new libdcp::Signer (chain, signer_key));
+}
+
+libdcp::Size
+fit_ratio_within (float ratio, libdcp::Size full_frame)
+{
+ if (ratio < full_frame.ratio ()) {
+ return libdcp::Size (full_frame.height * ratio, full_frame.height);
+ }
+
+ return libdcp::Size (full_frame.width, full_frame.width / ratio);
+}