+string
+entities_to_text (string e)
+{
+ boost::algorithm::replace_all (e, "%3A", ":");
+ boost::algorithm::replace_all (e, "%2F", "/");
+ return e;
+}
+
+int64_t
+divide_with_round (int64_t a, int64_t b)
+{
+ if (a % b >= (b / 2)) {
+ return (a + b - 1) / b;
+ } else {
+ return a / b;
+ }
+}
+
+/** Return a user-readable string summarising the versions of our dependencies */
+string
+dependency_version_summary ()
+{
+ stringstream s;
+ s << N_("libopenjpeg ") << opj_version () << N_(", ")
+ << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ")
+ << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ")
+ << N_("libavformat ") << ffmpeg_version_to_string (avformat_version()) << N_(", ")
+ << N_("libavutil ") << ffmpeg_version_to_string (avutil_version()) << N_(", ")
+ << N_("libswscale ") << ffmpeg_version_to_string (swscale_version()) << N_(", ")
+ << MagickVersion << N_(", ")
+ << N_("libssh ") << ssh_version (0) << N_(", ")
+ << N_("libdcp ") << dcp::version << N_(" git ") << dcp::git_commit;
+
+ return s.str ();
+}
+
+ScopedTemporary::ScopedTemporary ()
+ : _open (0)
+{
+ _file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path ();
+}
+
+ScopedTemporary::~ScopedTemporary ()
+{
+ close ();
+ boost::system::error_code ec;
+ boost::filesystem::remove (_file, ec);
+}
+
+char const *
+ScopedTemporary::c_str () const
+{
+ return _file.string().c_str ();
+}
+
+FILE*
+ScopedTemporary::open (char const * params)
+{
+ _open = fopen (c_str(), params);
+ return _open;
+}
+
+void
+ScopedTemporary::close ()
+{
+ if (_open) {
+ fclose (_open);
+ _open = 0;
+ }
+}