Be a bit more careful with fwrite.
[dcpomatic.git] / src / lib / util.cc
index abfdd2767c31a50f6a3342c684cc9fcea9a9c960..595c7e76eb38355bf014c5a05647fea714b8a9a7 100644 (file)
@@ -49,9 +49,6 @@ extern "C" {
 #include <libavcodec/avcodec.h>
 }
 #include <curl/curl.h>
-#ifdef DCPOMATIC_GRAPHICS_MAGICK
-#include <Magick++.h>
-#endif
 #include <glib.h>
 #include <pangomm/init.h>
 #include <boost/algorithm/string.hpp>
@@ -157,18 +154,27 @@ seconds_to_approximate_hms (int s)
 
        string ap;
 
-       bool const hours = h > 0;
-       bool const minutes = h < 6 && m > 0;
-       bool const seconds = h == 0 && m < 10 && s > 0;
+       bool hours = h > 0;
+       bool minutes = h < 6 && m > 0;
+       bool seconds = h == 0 && m < 10 && s > 0;
 
-       if (hours) {
-               if (m > 30 && !minutes) {
-                       /// TRANSLATORS: h here is an abbreviation for hours
-                       ap += locale_convert<string>(h + 1) + _("h");
-               } else {
-                       /// TRANSLATORS: h here is an abbreviation for hours
-                       ap += locale_convert<string>(h) + _("h");
+       if (m > 30 && !minutes) {
+               /* round up the hours */
+               ++h;
+       }
+       if (s > 30 && !seconds) {
+               /* round up the minutes */
+               ++m;
+               if (m == 60) {
+                       m = 0;
+                       minutes = false;
+                       ++h;
                }
+       }
+
+       if (hours) {
+               /// TRANSLATORS: h here is an abbreviation for hours
+               ap += locale_convert<string>(h) + _("h");
 
                if (minutes || seconds) {
                        ap += N_(" ");
@@ -176,14 +182,8 @@ seconds_to_approximate_hms (int s)
        }
 
        if (minutes) {
-               /* Minutes */
-               if (s > 30 && !seconds) {
-                       /// TRANSLATORS: m here is an abbreviation for minutes
-                       ap += locale_convert<string>(m + 1) + _("m");
-               } else {
-                       /// TRANSLATORS: m here is an abbreviation for minutes
-                       ap += locale_convert<string>(m) + _("m");
-               }
+               /// TRANSLATORS: m here is an abbreviation for minutes
+               ap += locale_convert<string>(m) + _("m");
 
                if (seconds) {
                        ap += N_(" ");
@@ -369,10 +369,6 @@ dcpomatic_setup ()
 
        curl_global_init (CURL_GLOBAL_ALL);
 
-#ifdef DCPOMATIC_GRAPHICS_MAGICK
-       Magick::InitializeMagick (0);
-#endif
-
        ui_thread = boost::this_thread::get_id ();
 }
 
@@ -448,7 +444,7 @@ digest_head_tail (vector<boost::filesystem::path> files, boost::uintmax_t size)
                }
 
                boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i]));
-               fread (p, 1, this_time, f);
+               checked_fread (p, this_time, f, files[i]);
                p += this_time;
                to_do -= this_time;
                fclose (f);
@@ -469,7 +465,7 @@ digest_head_tail (vector<boost::filesystem::path> files, boost::uintmax_t size)
 
                boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i]));
                dcpomatic_fseek (f, -this_time, SEEK_END);
-               fread (p, 1, this_time, f);
+               checked_fread (p, this_time, f, files[i]);
                p += this_time;
                to_do -= this_time;
                fclose (f);
@@ -574,7 +570,8 @@ valid_image_file (boost::filesystem::path f)
        return (
                ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" ||
                ext == ".png" || ext == ".bmp" || ext == ".tga" || ext == ".dpx" ||
-               ext == ".j2c" || ext == ".j2k" || ext == ".jp2" || ext == ".exr"
+               ext == ".j2c" || ext == ".j2k" || ext == ".jp2" || ext == ".exr" ||
+               ext == ".jpf"
                );
 }
 
@@ -718,7 +715,7 @@ careful_string_filter (string s)
        */
 
        string out;
-       string const allowed = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_%.";
+       string const allowed = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_%.+";
        for (size_t i = 0; i < s.size(); ++i) {
                if (allowed.find (s[i]) != string::npos) {
                        out += s[i];
@@ -785,3 +782,33 @@ increment_eyes (Eyes e)
 
        return EYES_LEFT;
 }
+
+void
+checked_fwrite (void const * ptr, size_t size, FILE* stream, boost::filesystem::path path)
+{
+       size_t N = fwrite (ptr, 1, size, stream);
+       if (N != size) {
+               if (ferror(stream)) {
+                       fclose (stream);
+                       throw FileError (String::compose("fwrite error %1", errno), path);
+               } else {
+                       fclose (stream);
+                       throw FileError ("Unexpected short write", path);
+               }
+       }
+}
+
+void
+checked_fread (void* ptr, size_t size, FILE* stream, boost::filesystem::path path)
+{
+       size_t N = fread (ptr, 1, size, stream);
+       if (N != size) {
+               if (ferror(stream)) {
+                       fclose (stream);
+                       throw FileError (String::compose("fread error %1", errno), path);
+               } else {
+                       fclose (stream);
+                       throw FileError ("Unexpected short read", path);
+               }
+       }
+}