From: Carl Hetherington Date: Fri, 29 Nov 2013 21:38:08 +0000 (+0000) Subject: Merge master. X-Git-Tag: v2.0.48~1108 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=bdbb254c18b100f8fa66a3707f6b515309d05685;hp=-c;p=dcpomatic.git Merge master. --- bdbb254c18b100f8fa66a3707f6b515309d05685 diff --combined src/lib/film.cc index d53d61a63,b1b868984..71836f254 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@@ -64,8 -64,6 +64,6 @@@ using std::multimap using std::pair; using std::map; using std::vector; - using std::ifstream; - using std::ofstream; using std::setfill; using std::min; using std::make_pair; @@@ -83,7 -81,7 +81,7 @@@ using boost::optional using libdcp::Size; using libdcp::Signer; -int const Film::state_version = 4; +int const Film::state_version = 5; /** Construct a Film object in a given directory. * @@@ -374,8 -372,6 +372,8 @@@ Film::read_metadata ( cxml::Document f ("Metadata"); f.read_file (file ("metadata.xml")); + + int const version = f.number_child ("Version"); _name = f.string_child ("Name"); _use_dci_name = f.bool_child ("UseDCIName"); @@@ -407,7 -403,7 +405,7 @@@ _three_d = f.bool_child ("ThreeD"); _interop = f.bool_child ("Interop"); _key = libdcp::Key (f.string_child ("Key")); - _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist")); + _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), version); _dirty = false; } diff --combined src/lib/util.cc index 98dec58d7,9dffffa98..ddc0a2974 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@@ -39,6 -39,9 +39,9 @@@ #include #include #include + #ifdef DCPOMATIC_WINDOWS + #include + #endif #include #include #include @@@ -80,7 -83,6 +83,6 @@@ using std::endl using std::vector; using std::hex; using std::setw; - using std::ifstream; using std::ios; using std::min; using std::max; @@@ -89,9 -91,7 +91,8 @@@ using std::multimap using std::istream; using std::numeric_limits; using std::pair; - using std::ofstream; using std::cout; +using std::streampos; using boost::shared_ptr; using boost::thread; using boost::lexical_cast; @@@ -261,8 -261,11 +262,11 @@@ seconds (struct timeval t LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *) { dbg::stack s; - ofstream f (backtrace_file.string().c_str()); - std::copy(s.begin(), s.end(), std::ostream_iterator(f, "\n")); + FILE* f = fopen_boost (backtrace_file, "w"); + for (dbg::stack::const_iterator i = s.begin(); i != s.end(); ++i) { + fprintf (f, "%p %s %d %s", i->instruction, i->function.c_str(), i->line, i->module.c_str()); + } + fclose (f); return EXCEPTION_CONTINUE_SEARCH; } #endif @@@ -277,6 -280,21 +281,21 @@@ dcpomatic_setup ( backtrace_file /= g_get_user_config_dir (); backtrace_file /= "backtrace.txt"; SetUnhandledExceptionFilter(exception_handler); + + /* Dark voodoo which, I think, gets boost::filesystem::path to + correctly convert UTF-8 strings to paths, and also paths + back to UTF-8 strings (on path::string()). + + After this, constructing boost::filesystem::paths from strings + converts from UTF-8 to UTF-16 inside the path. Then + path::string().c_str() gives UTF-8 and + path::c_str() gives UTF-16. + + This is all Windows-only. AFAICT Linux/OS X use UTF-8 everywhere, + so things are much simpler. + */ + std::locale::global (boost::locale::generator().generate ("")); + boost::filesystem::path::imbue (std::locale ()); #endif avfilter_register_all (); @@@ -387,42 -405,82 +406,42 @@@ md5_digest (void const * data, int size return s.str (); } -/** @param file File name. - * @return MD5 digest of file's contents. - */ -string -md5_digest (boost::filesystem::path file) -{ - FILE* f = fopen_boost (file, "rb"); - if (!f) { - throw OpenFileError (file.string()); - } - - boost::uintmax_t bytes = boost::filesystem::file_size (file); - - boost::uintmax_t const buffer_size = 64 * 1024; - char buffer[buffer_size]; - - MD5_CTX md5_context; - MD5_Init (&md5_context); - while (bytes > 0) { - int const t = min (bytes, buffer_size); - fread (buffer, 1, t, f); - MD5_Update (&md5_context, buffer, t); - bytes -= t; - } - - unsigned char digest[MD5_DIGEST_LENGTH]; - MD5_Final (digest, &md5_context); - fclose (f); - - stringstream s; - for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { - s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]); - } - - return s.str (); -} - /** @param job Optional job for which to report progress */ string -md5_digest_directory (boost::filesystem::path directory, shared_ptr job) +md5_digest (vector files, shared_ptr job) { - int const buffer_size = 64 * 1024; + boost::uintmax_t 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; - } + vector sizes; + for (size_t i = 0; i < files.size(); ++i) { + sizes.push_back (boost::filesystem::file_size (files[i])); } - int j = 0; - for (boost::filesystem::directory_iterator i(directory); i != boost::filesystem::directory_iterator(); ++i) { - FILE* f = fopen_boost (i->path(), "rb"); + for (size_t i = 0; i < files.size(); ++i) { - ifstream f (files[i].string().c_str(), std::ios::binary); - if (!f.good ()) { ++ FILE* f = fopen_boost (files[i], "rb"); + if (!f) { - throw OpenFileError (i->path().string()); + throw OpenFileError (files[i].string()); } - - f.seekg (0, std::ios::end); - streampos const bytes = f.tellg (); - f.seekg (0, std::ios::beg); - streampos remaining = bytes; - boost::uintmax_t bytes = boost::filesystem::file_size (i->path ()); ++ boost::uintmax_t const bytes = boost::filesystem::file_size (files[i]); ++ boost::uintmax_t remaining = bytes; + - while (bytes > 0) { - int const t = min (bytes, buffer_size); + while (remaining > 0) { - int const t = min (remaining, streampos (buffer_size)); - f.read (buffer, t); ++ int const t = min (remaining, buffer_size); + fread (buffer, 1, t, f); MD5_Update (&md5_context, buffer, t); - bytes -= t; - } + remaining -= t; - if (job) { - job->set_progress (float (j) / files); - ++j; + if (job) { + job->set_progress ((float (i) + 1 - float(remaining) / bytes) / files.size ()); + } } + + fclose (f); } unsigned char digest[MD5_DIGEST_LENGTH]; diff --combined src/lib/wscript index ebd316a0c,5098d4069..1699c5ec8 --- a/src/lib/wscript +++ b/src/lib/wscript @@@ -22,7 -22,6 +22,7 @@@ sources = "" encoder.cc examine_content_job.cc exceptions.cc + file_group.cc filter_graph.cc ffmpeg.cc ffmpeg_content.cc @@@ -31,13 -30,13 +31,13 @@@ film.cc filter.cc image.cc + image_content.cc + image_decoder.cc + image_examiner.cc job.cc job_manager.cc kdm.cc log.cc - moving_image_content.cc - moving_image_decoder.cc - moving_image_examiner.cc player.cc playlist.cc ratio.cc @@@ -49,6 -48,9 +49,6 @@@ sndfile_content.cc sndfile_decoder.cc sound_processor.cc - still_image_content.cc - still_image_decoder.cc - still_image_examiner.cc subtitle_content.cc subtitle_decoder.cc timer.cc @@@ -72,7 -74,7 +72,7 @@@ def build(bld) obj.export_includes = ['..'] obj.uselib = """ AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE - BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 + BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 SNDFILE OPENJPEG POSTPROC TIFF MAGICK SSH DCP CXML GLIB LZMA XML++ CURL ZIP QUICKMAIL """ @@@ -80,7 -82,7 +80,7 @@@ obj.source = sources + ' version.cc' if bld.env.TARGET_WINDOWS: - obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY SHLWAPI MSWSOCK' + obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY SHLWAPI MSWSOCK BOOST_LOCALE' obj.source += ' stack.cpp' if bld.env.STATIC: obj.uselib += ' XML++' diff --combined src/tools/dcpomatic.cc index a4239bd21,2a0cb9cd3..b4ec1d77d --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@@ -62,7 -62,6 +62,6 @@@ using std::map using std::make_pair; using std::list; using std::exception; - using std::ofstream; using boost::shared_ptr; using boost::dynamic_pointer_cast; @@@ -246,8 -245,23 +245,24 @@@ public Frame (wxString const & title) : wxFrame (NULL, -1, title) , _servers_list_dialog (0) + , _hints_dialog (0) { + #ifdef DCPOMATIC_WINDOWS_CONSOLE + AllocConsole(); + + HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); + int hCrt = _open_osfhandle((intptr_t) handle_out, _O_TEXT); + FILE* hf_out = _fdopen(hCrt, "w"); + setvbuf(hf_out, NULL, _IONBF, 1); + *stdout = *hf_out; + + HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE); + hCrt = _open_osfhandle((intptr_t) handle_in, _O_TEXT); + FILE* hf_in = _fdopen(hCrt, "r"); + setvbuf(hf_in, NULL, _IONBF, 128); + *stdin = *hf_in; + #endif + wxMenuBar* bar = new wxMenuBar; setup_menu (bar); SetMenuBar (bar); @@@ -333,7 -347,7 +348,7 @@@ private std_to_wx ( String::compose (wx_to_std (_("The directory %1 already exists and is not empty. " "Are you sure you want to use it?")), - d->get_path().c_str()) + d->get_path().string().c_str()) ) )) { return; diff --combined src/wx/film_editor.cc index 99d607731,92fb9d0f3..bf13620e5 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@@ -36,7 -36,8 +36,7 @@@ #include "lib/filter.h" #include "lib/ratio.h" #include "lib/config.h" -#include "lib/still_image_content.h" -#include "lib/moving_image_content.h" +#include "lib/image_content.h" #include "lib/ffmpeg_content.h" #include "lib/sndfile_content.h" #include "lib/dcp_content_type.h" @@@ -150,7 -151,7 +150,7 @@@ FilmEditor::make_dcp_panel ( } ++r; - _encrypted = new wxCheckBox (_dcp_panel, wxID_ANY, wxT ("Encrypted")); + _encrypted = new wxCheckBox (_dcp_panel, wxID_ANY, _("Encrypted")); grid->Add (_encrypted, wxGBPosition (r, 0), wxGBSpan (1, 2)); ++r; @@@ -730,11 -731,14 +730,14 @@@ FilmEditor::setup_content ( void FilmEditor::content_add_file_clicked () { - wxFileDialog* d = new wxFileDialog (this, _("Choose a file or files"), wxT (""), wxT (""), wxT ("*.*"), wxFD_MULTIPLE); + /* The wxFD_CHANGE_DIR here prevents a `could not set working directory' error 123 on Windows when using + non-Latin filenames or paths. + */ + wxFileDialog* d = new wxFileDialog (this, _("Choose a file or files"), wxT (""), wxT (""), wxT ("*.*"), wxFD_MULTIPLE | wxFD_CHANGE_DIR); int const r = d->ShowModal (); - d->Destroy (); if (r != wxID_OK) { + d->Destroy (); return; } @@@ -744,8 -748,10 +747,10 @@@ /* XXX: check for lots of files here and do something */ for (unsigned int i = 0; i < paths.GetCount(); ++i) { - _film->examine_and_add_content (content_factory (_film, wx_to_std (paths[i]))); + _film->examine_and_add_content (content_factory (_film, wx_to_std (d->GetPath ()))); } + + d->Destroy (); } void @@@ -760,8 -766,8 +765,8 @@@ FilmEditor::content_add_folder_clicked } _film->examine_and_add_content ( - shared_ptr ( - new MovingImageContent (_film, boost::filesystem::path (wx_to_std (d->GetPath ()))) + shared_ptr ( + new ImageContent (_film, boost::filesystem::path (wx_to_std (d->GetPath ()))) ) ); } @@@ -820,9 -826,7 +825,9 @@@ FilmEditor::selected_content ( break; } - sel.push_back (_film->content()[s]); + if (s < int (_film->content().size ())) { + sel.push_back (_film->content()[s]); + } } return sel; diff --combined test/wscript index 5a1114904,76de63a52..4ae49b087 --- a/test/wscript +++ b/test/wscript @@@ -15,32 -15,32 +15,33 @@@ def build(bld) obj.uselib = 'BOOST_TEST DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML' obj.use = 'libdcpomatic' obj.source = """ - test.cc + 4k_test.cc + audio_analysis_test.cc - scaling_test.cc - film_metadata_test.cc - frame_rate_test.cc - colour_conversion_test.cc audio_delay_test.cc - silence_padding_test.cc audio_merger_test.cc - resampler_test.cc + black_fill_test.cc + client_server_test.cc + colour_conversion_test.cc ffmpeg_audio_test.cc - threed_test.cc - play_test.cc - ffmpeg_pts_offset.cc + ffmpeg_dcp_test.cc ffmpeg_examiner_test.cc - black_fill_test.cc - ratio_test.cc - pixel_formats_test.cc + ffmpeg_pts_offset.cc + file_group_test.cc + film_metadata_test.cc + frame_rate_test.cc + image_test.cc + job_test.cc make_black_test.cc + pixel_formats_test.cc + play_test.cc + ratio_test.cc + resampler_test.cc + scaling_test.cc + silence_padding_test.cc stream_test.cc + test.cc + threed_test.cc util_test.cc - ffmpeg_dcp_test.cc - job_test.cc - client_server_test.cc - image_test.cc - 4k_test.cc """ obj.target = 'unit-tests'