diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-07-22 16:32:37 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-07-22 16:32:37 +0100 |
| commit | 0f60e0f52c986f18764822de78b82b4163909f0c (patch) | |
| tree | 9fd45bd68de68ee47551efcdcf955344ad1fc87a /src | |
| parent | 7523c7f0ab64f075ca535071b780098f6c05fce6 (diff) | |
Option to draw a border around the content's image (#391).
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/film.cc | 2 | ||||
| -rw-r--r-- | src/lib/player.cc | 2 | ||||
| -rw-r--r-- | src/lib/player_video.cc | 10 | ||||
| -rw-r--r-- | src/lib/player_video.h | 8 | ||||
| -rw-r--r-- | src/lib/util.cc | 17 | ||||
| -rw-r--r-- | src/lib/util.h | 3 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 10 | ||||
| -rw-r--r-- | src/lib/video_content.h | 2 | ||||
| -rw-r--r-- | src/wx/film_viewer.cc | 33 | ||||
| -rw-r--r-- | src/wx/film_viewer.h | 4 | ||||
| -rw-r--r-- | src/wx/video_panel.cc | 2 |
11 files changed, 71 insertions, 22 deletions
diff --git a/src/lib/film.cc b/src/lib/film.cc index 0de6f2ded..0891838ff 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1071,7 +1071,7 @@ Film::full_frame () const dcp::Size Film::frame_size () const { - return fit_ratio_within (container()->ratio(), full_frame ()); + return fit_ratio_within (container()->ratio(), full_frame (), 1); } dcp::EncryptedKDM diff --git a/src/lib/player.cc b/src/lib/player.cc index 06f9e1365..e46d539f8 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -342,7 +342,7 @@ Player::get_video (DCPTime time, bool accurate) return pvf; } - dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size ()); + dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size (), _approximate_size ? 4 : 1); if (_approximate_size) { image_size.width &= ~3; image_size.height &= ~3; diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc index a44264ced..8fd966e5f 100644 --- a/src/lib/player_video.cc +++ b/src/lib/player_video.cc @@ -111,8 +111,6 @@ PlayerVideo::image (bool burn_subtitle) const shared_ptr<Image> out = im->crop_scale_window (total_crop, _inter_size, _out_size, _scaler, PIX_FMT_RGB24, true); - Position<int> const container_offset ((_out_size.width - _inter_size.width) / 2, (_out_size.height - _inter_size.width) / 2); - if (burn_subtitle && _subtitle.image) { out->alpha_blend (_subtitle.image, _subtitle.position); } @@ -171,3 +169,11 @@ PlayerVideo::j2k () const assert (j2k); return j2k->j2k (); } + +Position<int> +PlayerVideo::inter_position () const +{ + return Position<int> ((_out_size.width - _inter_size.width) / 2, (_out_size.height - _inter_size.height) / 2); +} + + diff --git a/src/lib/player_video.h b/src/lib/player_video.h index 4fe8712d4..74e05d1e9 100644 --- a/src/lib/player_video.h +++ b/src/lib/player_video.h @@ -62,6 +62,14 @@ public: return _colour_conversion; } + /** @return Position of the content within the overall image once it has been scaled up */ + Position<int> inter_position () const; + + /** @return Size of the content within the overall image once it has been scaled up */ + dcp::Size inter_size () const { + return _inter_size; + } + private: boost::shared_ptr<const ImageProxy> _in; DCPTime _time; diff --git a/src/lib/util.cc b/src/lib/util.cc index cc8d59f21..60953b544 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -636,6 +636,17 @@ stride_round_up (int c, int const * stride, int t) return a - (a % t); } +/** @param n A number. + * @param r Rounding `boundary' (must be a power of 2) + * @return n rounded to the nearest r + */ +int +round_to (float n, int r) +{ + assert (r == 1 || r == 2 || r == 4); + return int (n + float(r) / 2) &~ (r - 1); +} + /** Read a sequence of key / value pairs from a text stream; * the keys are the first words on the line, and the values are * the remainder of the line following the key. Lines beginning @@ -837,13 +848,13 @@ split_get_request (string url) } dcp::Size -fit_ratio_within (float ratio, dcp::Size full_frame) +fit_ratio_within (float ratio, dcp::Size full_frame, int round) { if (ratio < full_frame.ratio ()) { - return dcp::Size (rint (full_frame.height * ratio), full_frame.height); + return dcp::Size (round_to (full_frame.height * ratio, round), full_frame.height); } - return dcp::Size (full_frame.width, rint (full_frame.width / ratio)); + return dcp::Size (full_frame.width, round_to (full_frame.width / ratio, round)); } void * diff --git a/src/lib/util.h b/src/lib/util.h index b7dc978e3..1bbdfb2cf 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -66,11 +66,12 @@ extern bool valid_image_file (boost::filesystem::path); extern boost::filesystem::path mo_path (); #endif extern std::string tidy_for_filename (std::string); -extern dcp::Size fit_ratio_within (float ratio, dcp::Size); +extern dcp::Size fit_ratio_within (float ratio, dcp::Size, int); extern std::string entities_to_text (std::string e); extern std::map<std::string, std::string> split_get_request (std::string url); extern int dcp_audio_frame_rate (int); extern int stride_round_up (int, int const *, int); +extern int round_to (float n, int r); extern std::multimap<std::string, std::string> read_key_value (std::istream& s); extern int get_required_int (std::multimap<std::string, std::string> const & kv, std::string k); extern float get_required_float (std::multimap<std::string, std::string> const & kv, std::string k); diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 0d9a8fc45..0a3e378ee 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -508,25 +508,25 @@ VideoContentScale::name () const * @param film_container The size of the film's image. */ dcp::Size -VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container) const +VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container, int round) const { if (_ratio) { - return fit_ratio_within (_ratio->ratio (), display_container); + return fit_ratio_within (_ratio->ratio (), display_container, round); } dcp::Size const ac = c->video_size_after_crop (); /* Force scale if the film_container is smaller than the content's image */ if (_scale || film_container.width < ac.width || film_container.height < ac.height) { - return fit_ratio_within (ac.ratio (), display_container); + return fit_ratio_within (ac.ratio (), display_container, 1); } /* Scale the image so that it will be in the right place in film_container, even if display_container is a different size. */ return dcp::Size ( - c->video_size().width * float(display_container.width) / film_container.width, - c->video_size().height * float(display_container.height) / film_container.height + round_to (c->video_size().width * float(display_container.width) / film_container.width, round), + round_to (c->video_size().height * float(display_container.height) / film_container.height, round) ); } diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 7d9cb4f8f..dc7de8d54 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -45,7 +45,7 @@ public: VideoContentScale (bool); VideoContentScale (cxml::NodePtr); - dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size) const; + dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size, int round) const; std::string id () const; std::string name () const; void as_xml (xmlpp::Node *) const; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 80b12bf76..96e20a281 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -58,6 +58,7 @@ using dcp::Size; FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p) : wxPanel (p) , _panel (new wxPanel (this)) + , _outline_content (new wxCheckBox (this, wxID_ANY, _("Outline content"))) , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096)) , _back_button (new wxButton (this, wxID_ANY, wxT("<"))) , _forward_button (new wxButton (this, wxID_ANY, wxT(">"))) @@ -77,6 +78,8 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p) _v_sizer->Add (_panel, 1, wxEXPAND); + _v_sizer->Add (_outline_content, 0, wxALL, DCPOMATIC_SIZER_GAP); + wxBoxSizer* h_sizer = new wxBoxSizer (wxHORIZONTAL); wxBoxSizer* time_sizer = new wxBoxSizer (wxVERTICAL); @@ -97,6 +100,7 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p) _panel->Bind (wxEVT_PAINT, boost::bind (&FilmViewer::paint_panel, this)); _panel->Bind (wxEVT_SIZE, boost::bind (&FilmViewer::panel_sized, this, _1)); + _outline_content->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilmViewer::refresh_panel, this)); _slider->Bind (wxEVT_SCROLL_THUMBTRACK, boost::bind (&FilmViewer::slider_moved, this)); _slider->Bind (wxEVT_SCROLL_PAGEUP, boost::bind (&FilmViewer::slider_moved, this)); _slider->Bind (wxEVT_SCROLL_PAGEDOWN, boost::bind (&FilmViewer::slider_moved, this)); @@ -146,6 +150,13 @@ FilmViewer::set_film (shared_ptr<Film> f) } void +FilmViewer::refresh_panel () +{ + _panel->Refresh (); + _panel->Update (); +} + +void FilmViewer::get (DCPTime p, bool accurate) { if (!_player) { @@ -158,6 +169,8 @@ FilmViewer::get (DCPTime p, bool accurate) _frame = pvf.front()->image (true); _frame = _frame->scale (_frame->size(), Scaler::from_id ("fastbilinear"), PIX_FMT_RGB24, false); _position = pvf.front()->time (); + _inter_position = pvf.front()->inter_position (); + _inter_size = pvf.front()->inter_size (); } catch (dcp::DCPReadError& e) { /* This can happen on the following sequence of events: * - load encrypted DCP @@ -178,8 +191,7 @@ FilmViewer::get (DCPTime p, bool accurate) } set_position_text (); - _panel->Refresh (); - _panel->Update (); + refresh_panel (); _last_get_accurate = accurate; } @@ -228,9 +240,15 @@ FilmViewer::paint_panel () dc.SetPen (p); dc.SetBrush (b); dc.DrawRectangle (0, _out_size.height, _panel_size.width, _panel_size.height - _out_size.height); - } -} + } + if (_outline_content->GetValue ()) { + wxPen p (wxColour (255, 0, 0), 2); + dc.SetPen (p); + dc.SetBrush (*wxTRANSPARENT_BRUSH); + dc.DrawRectangle (_inter_position.x, _inter_position.y, _inter_size.width, _inter_size.height); + } +} void FilmViewer::slider_moved () @@ -252,6 +270,7 @@ FilmViewer::panel_sized (wxSizeEvent& ev) { _panel_size.width = ev.GetSize().GetWidth(); _panel_size.height = ev.GetSize().GetHeight(); + calculate_sizes (); get (_position, _last_get_accurate); } @@ -271,18 +290,18 @@ FilmViewer::calculate_sizes () if (panel_ratio < film_ratio) { /* panel is less widscreen than the film; clamp width */ _out_size.width = _panel_size.width; - _out_size.height = _out_size.width / film_ratio; + _out_size.height = rint (_out_size.width / film_ratio); } else { /* panel is more widescreen than the film; clamp height */ _out_size.height = _panel_size.height; - _out_size.width = _out_size.height * film_ratio; + _out_size.width = rint (_out_size.height * film_ratio); } /* Catch silly values */ _out_size.width = max (64, _out_size.width); _out_size.height = max (64, _out_size.height); - /* The player will round its image down to the nearest 4 pixels + /* The player will round its image size down to the next lowest 4 pixels to speed up its scale, so do similar here to avoid black borders around things. This is a bit of a hack. */ diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 189b379bf..930937596 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -54,12 +54,14 @@ private: void player_changed (bool); void set_position_text (); void get (DCPTime, bool); + void refresh_panel (); boost::shared_ptr<Film> _film; boost::shared_ptr<Player> _player; wxSizer* _v_sizer; wxPanel* _panel; + wxCheckBox* _outline_content; wxSlider* _slider; wxButton* _back_button; wxButton* _forward_button; @@ -70,6 +72,8 @@ private: boost::shared_ptr<const Image> _frame; DCPTime _position; + Position<int> _inter_position; + dcp::Size _inter_size; /** Size of our output (including padding if we have any) */ dcp::Size _out_size; diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index d8fdf2d02..facd0f3d4 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -309,7 +309,7 @@ VideoPanel::setup_description () } dcp::Size const container_size = _parent->film()->frame_size (); - dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size); + dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size, 1); if (scaled != vcs->video_size_after_crop ()) { d << wxString::Format ( |
