Hand-apply 63b62aa703c2628b27b577114081b265f237dadb from master;
[dcpomatic.git] / src / lib / util.cc
index c9685aa44ff3ee811e1f7e77e052b8047ca8ff1d..bf4c7424417e92dde0de6a1127415a72fe061ee5 100644 (file)
 #include <glib.h>
 #include <openjpeg.h>
 #include <pangomm/init.h>
+#ifdef DCPOMATIC_IMAGE_MAGICK
 #include <magick/MagickCore.h>
+#else
+#include <magick/common.h>
+#include <magick/magick_config.h>
+#endif
 #include <magick/version.h>
 #include <dcp/version.h>
 #include <dcp/util.h>
@@ -151,14 +156,11 @@ seconds_to_approximate_hms (int s)
 
        if (hours) {
                if (m > 30 && !minutes) {
-                       ap << (h + 1) << N_(" ") << _("hours");
+                       /// TRANSLATORS: h here is an abbreviation for hours
+                       ap << (h + 1) << _("h");
                } else {
-                       ap << h << N_(" ");
-                       if (h == 1) {
-                               ap << _("hour");
-                       } else {
-                               ap << _("hours");
-                       }
+                       /// TRANSLATORS: h here is an abbreviation for hours
+                       ap << h << _("h");
                }
 
                if (minutes | seconds) {
@@ -169,14 +171,11 @@ seconds_to_approximate_hms (int s)
        if (minutes) {
                /* Minutes */
                if (s > 30 && !seconds) {
-                       ap << (m + 1) << N_(" ") << _("minutes");
+                       /// TRANSLATORS: m here is an abbreviation for minutes
+                       ap << (m + 1) << _("m");
                } else {
-                       ap << m << N_(" ");
-                       if (m == 1) {
-                               ap << _("minute");
-                       } else {
-                               ap << _("minutes");
-                       }
+                       /// TRANSLATORS: m here is an abbreviation for minutes
+                       ap << m << _("m");
                }
 
                if (seconds) {
@@ -186,12 +185,8 @@ seconds_to_approximate_hms (int s)
 
        if (seconds) {
                /* Seconds */
-               ap << s << N_(" ");
-               if (s == 1) {
-                       ap << _("second");
-               } else {
-                       ap << _("seconds");
-               }
+               /// TRANSLATORS: s here is an abbreviation for seconds
+               ap << s << _("s");
        }
 
        return ap.str ();
@@ -287,6 +282,12 @@ LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *)
 }
 #endif
 
+void
+set_backtrace_file (boost::filesystem::path p)
+{
+       backtrace_file = p;
+}
+
 /* From http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c */
 void
 terminate ()
@@ -322,8 +323,9 @@ void
 dcpomatic_setup ()
 {
 #ifdef DCPOMATIC_WINDOWS
-       backtrace_file /= g_get_user_config_dir ();
-       backtrace_file /= "backtrace.txt";
+       boost::filesystem::path p = g_get_user_config_dir ();
+       p /= "backtrace.txt";
+       set_backtrace_file (p);
        SetUnhandledExceptionFilter(exception_handler);
 
        /* Dark voodoo which, I think, gets boost::filesystem::path to
@@ -383,35 +385,42 @@ mo_path ()
 }
 #endif
 
+#ifdef DCPOMATIC_OSX
+boost::filesystem::path
+mo_path ()
+{
+       return "DCP-o-matic 2.app/Contents/Resources";
+}
+#endif
+
 void
 dcpomatic_setup_gettext_i18n (string lang)
 {
-#ifdef DCPOMATIC_POSIX
+#ifdef DCPOMATIC_LINUX
        lang += ".UTF8";
 #endif
 
        if (!lang.empty ()) {
-               /* Override our environment language; this is essential on
-                  Windows.
+               /* Override our environment language.  Note that the caller must not
+                  free the string passed into putenv().
                */
-               char cmd[64];
-               snprintf (cmd, sizeof(cmd), "LANGUAGE=%s", lang.c_str ());
-               putenv (cmd);
-               snprintf (cmd, sizeof(cmd), "LANG=%s", lang.c_str ());
-               putenv (cmd);
-               snprintf (cmd, sizeof(cmd), "LC_ALL=%s", lang.c_str ());
-               putenv (cmd);
+               string s = String::compose ("LANGUAGE=%1", lang);
+               putenv (strdup (s.c_str ()));
+               s = String::compose ("LANG=%1", lang);
+               putenv (strdup (s.c_str ()));
+               s = String::compose ("LC_ALL=%1", lang);
+               putenv (strdup (s.c_str ()));
        }
 
        setlocale (LC_ALL, "");
        textdomain ("libdcpomatic");
 
-#ifdef DCPOMATIC_WINDOWS
+#if defined(DCPOMATIC_WINDOWS) || defined(DCPOMATIC_OSX)
        bindtextdomain ("libdcpomatic", mo_path().string().c_str());
        bind_textdomain_codeset ("libdcpomatic", "UTF8");
 #endif 
 
-#ifdef DCPOMATIC_POSIX
+#ifdef DCPOMATIC_LINUX
        bindtextdomain ("libdcpomatic", POSIX_LOCALE_PREFIX);
 #endif
 }
@@ -465,7 +474,10 @@ md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
 
                while (remaining > 0) {
                        int const t = min (remaining, buffer_size);
-                       fread (buffer, 1, t, f);
+                       int const r = fread (buffer, 1, t, f);
+                       if (r != t) {
+                               throw ReadFileError (files[i], errno);
+                       }
                        digester.add (buffer, t);
                        remaining -= t;
 
@@ -555,7 +567,7 @@ Socket::accept (int port)
        _acceptor->async_accept (_socket, boost::lambda::var(ec) = boost::lambda::_1);
        do {
                _io_service.run_one ();
-       } while (ec == boost::asio::error::would_block );
+       } while (ec == boost::asio::error::would_block);
 
        delete _acceptor;
        _acceptor = 0;
@@ -755,10 +767,9 @@ audio_channel_name (int c)
 {
        assert (MAX_DCP_AUDIO_CHANNELS == 12);
 
-       /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency
-          enhancement channel (sub-woofer).  HI is the hearing-impaired audio track and
-          VI is the visually-impaired audio track (audio describe).
-       */
+       /// TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency
+       /// enhancement channel (sub-woofer).  HI is the hearing-impaired audio track and
+       /// VI is the visually-impaired audio track (audio describe).
        string const channels[] = {
                _("Left"),
                _("Right"),
@@ -782,7 +793,19 @@ 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" || ext == ".dpx");
+       return (
+               ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" ||
+               ext == ".png" || ext == ".bmp" || ext == ".tga" || ext == ".dpx" ||
+               ext == ".j2c" || ext == ".j2k"
+               );
+}
+
+bool
+valid_j2k_file (boost::filesystem::path f)
+{
+       string ext = f.extension().string();
+       transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+       return (ext == ".j2k" || ext == ".j2c");
 }
 
 string