Use a Crop struct and use it to speed up cropping a bit.
authorCarl Hetherington <cth@carlh.net>
Fri, 27 Jul 2012 21:30:35 +0000 (22:30 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 27 Jul 2012 21:30:35 +0000 (22:30 +0100)
src/lib/decoder.cc
src/lib/film.cc
src/lib/film.h
src/lib/film_state.cc
src/lib/film_state.h
src/lib/util.cc
src/lib/util.h
src/wx/film_editor.cc
src/wx/film_viewer.cc
test/test.cc

index abdaa59d92f10fa88fc89e6d49aa3fa3a1ad8060..c6982ef46b698b05b9e234b5ce3179ec8cbd614d 100644 (file)
@@ -401,7 +401,7 @@ Decoder::setup_video_filters ()
        
        if (_opt->apply_crop) {
                size_after_crop = _fs->cropped_size (native_size ());
-               fs << crop_string (Position (_fs->left_crop, _fs->top_crop), size_after_crop);
+               fs << crop_string (Position (_fs->crop.left, _fs->crop.top), size_after_crop);
        } else {
                size_after_crop = native_size ();
                fs << crop_string (Position (0, 0), size_after_crop);
index a9d6e8f997ea0f1a11b3737e6bbf944e72ca8888..cb0a44a456c03aad127e35157e453768a0823afc 100644 (file)
@@ -223,48 +223,48 @@ Film::set_dcp_content_type (DCPContentType const * t)
 void
 Film::set_left_crop (int c)
 {
-       if (c == _state.left_crop) {
+       if (c == _state.crop.left) {
                return;
        }
        
-       _state.left_crop = c;
-       signal_changed (LEFT_CROP);
+       _state.crop.left = c;
+       signal_changed (CROP);
 }
 
 /** Set the number of pixels by which to crop the right of the source video */
 void
 Film::set_right_crop (int c)
 {
-       if (c == _state.right_crop) {
+       if (c == _state.crop.right) {
                return;
        }
 
-       _state.right_crop = c;
-       signal_changed (RIGHT_CROP);
+       _state.crop.right = c;
+       signal_changed (CROP);
 }
 
 /** Set the number of pixels by which to crop the top of the source video */
 void
 Film::set_top_crop (int c)
 {
-       if (c == _state.top_crop) {
+       if (c == _state.crop.top) {
                return;
        }
        
-       _state.top_crop = c;
-       signal_changed (TOP_CROP);
+       _state.crop.top = c;
+       signal_changed (CROP);
 }
 
 /** Set the number of pixels by which to crop the bottom of the source video */
 void
 Film::set_bottom_crop (int c)
 {
-       if (c == _state.bottom_crop) {
+       if (c == _state.crop.bottom) {
                return;
        }
        
-       _state.bottom_crop = c;
-       signal_changed (BOTTOM_CROP);
+       _state.crop.bottom = c;
+       signal_changed (CROP);
 }
 
 /** Set the filters to apply to the image when generating thumbnails
@@ -425,7 +425,7 @@ Film::j2k_dir () const
        stringstream s;
        s << _state.format->id()
          << "_" << _state.content_digest
-         << "_" << left_crop() << "_" << right_crop() << "_" << top_crop() << "_" << bottom_crop()
+         << "_" << crop().left << "_" << crop().right << "_" << crop().top << "_" << crop().bottom
          << "_" << f.first << "_" << f.second
          << "_" << _state.scaler->id();
 
index f214d411fbd8f8ca3ee5300b2434230b82507e1f..dc766252dc6e5ea91d98dab1a251fc593f950157 100644 (file)
@@ -70,24 +70,9 @@ public:
                return _state.name;
        }
 
-       /** @return number of pixels to crop from the top of the original picture */
-       int top_crop () const {
-               return _state.top_crop;
-       }
-
-       /** @return number of pixels to crop from the bottom of the original picture */
-       int bottom_crop () const {
-               return _state.bottom_crop;
-       }
-
-       /** @return number of pixels to crop from the left-hand side of the original picture */
-       int left_crop () const {
-               return _state.left_crop;
-       }
-
-       /** @return number of pixels to crop from the right-hand side of the original picture */
-       int right_crop () const {
-               return _state.right_crop;
+       /** @return number of pixels to crop from the sides of the original picture */
+       Crop crop () const {
+               return _state.crop;
        }
 
        /** @return the format to present this film in (flat, scope, etc.) */
@@ -219,10 +204,7 @@ public:
                CONTENT,
                DCP_CONTENT_TYPE,
                FORMAT,
-               LEFT_CROP,
-               RIGHT_CROP,
-               TOP_CROP,
-               BOTTOM_CROP,
+               CROP,
                FILTERS,
                SCALER,
                DCP_FRAMES,
index 29bf71db332be8045f2c290823b8c469718d2742..e23bf9148595b8905b8f31cfccb48ab9f80d6e51 100644 (file)
@@ -55,10 +55,10 @@ FilmState::write_metadata (ofstream& f) const
        if (format) {
                f << "format " << format->as_metadata () << "\n";
        }
-       f << "left_crop " << left_crop << "\n";
-       f << "right_crop " << right_crop << "\n";
-       f << "top_crop " << top_crop << "\n";
-       f << "bottom_crop " << bottom_crop << "\n";
+       f << "left_crop " << crop.left << "\n";
+       f << "right_crop " << crop.right << "\n";
+       f << "top_crop " << crop.top << "\n";
+       f << "bottom_crop " << crop.bottom << "\n";
        for (vector<Filter const *>::const_iterator i = filters.begin(); i != filters.end(); ++i) {
                f << "filter " << (*i)->id () << "\n";
        }
@@ -114,13 +114,13 @@ FilmState::read_metadata (string k, string v)
        } else if (k == "format") {
                format = Format::from_metadata (v);
        } else if (k == "left_crop") {
-               left_crop = atoi (v.c_str ());
+               crop.left = atoi (v.c_str ());
        } else if (k == "right_crop") {
-               right_crop = atoi (v.c_str ());
+               crop.right = atoi (v.c_str ());
        } else if (k == "top_crop") {
-               top_crop = atoi (v.c_str ());
+               crop.top = atoi (v.c_str ());
        } else if (k == "bottom_crop") {
-               bottom_crop = atoi (v.c_str ());
+               crop.bottom = atoi (v.c_str ());
        } else if (k == "filter") {
                filters.push_back (Filter::from_id (v));
        } else if (k == "scaler") {
@@ -214,8 +214,8 @@ FilmState::thumb_frame (int n) const
 Size
 FilmState::cropped_size (Size s) const
 {
-       s.width -= left_crop + right_crop;
-       s.height -= top_crop + bottom_crop;
+       s.width -= crop.left + crop.right;
+       s.height -= crop.top + crop.bottom;
        return s;
 }
 
index 1df2dc95d7fe88e77cf086a129f928fec01d83a4..12d44cdce23797557aac7c23a8229b5835094298 100644 (file)
@@ -55,10 +55,6 @@ public:
                : dcp_content_type (0)
                , frames_per_second (0)
                , format (0)
-               , left_crop (0)
-               , right_crop (0)
-               , top_crop (0)
-               , bottom_crop (0)
                , scaler (Scaler::from_id ("bicubic"))
                , dcp_frames (0)
                , dcp_trim_action (CUT)
@@ -106,14 +102,7 @@ public:
        float frames_per_second;
        /** The format to present this Film in (flat, scope, etc.) */
        Format const * format;
-       /** Number of pixels to crop from the left-hand side of the original picture */
-       int left_crop;
-       /** Number of pixels to crop from the right-hand side of the original picture */
-       int right_crop;
-       /** Number of pixels to crop from the top of the original picture */
-       int top_crop;
-       /** Number of pixels to crop from the bottom of the original picture */
-       int bottom_crop;
+       Crop crop;
        /** Video filters that should be used when generating DCPs */
        std::vector<Filter const *> filters;
        /** Scaler algorithm to use */
index c154339537c34421c15dcde256d78d6938c09135..5106f3182e7cc74e67a8cdaf5a3fae3653153a19 100644 (file)
@@ -491,3 +491,13 @@ dcp_audio_sample_rate (int fs)
 
        return 96000;
 }
+
+bool operator== (Crop const & a, Crop const & b)
+{
+       return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
+}
+
+bool operator!= (Crop const & a, Crop const & b)
+{
+       return !(a == b);
+}
index 1faef0cd3e8c1455801b8b42b63547b89b8ee274..16afb7bb6fa92be941963039dd8a12e41e4d234e 100644 (file)
@@ -103,6 +103,19 @@ struct Size
        int height;
 };
 
+struct Crop
+{
+       Crop () : left (0), right (0), top (0), bottom (0) {}
+       
+       int left;
+       int right;
+       int top;
+       int bottom;
+};
+
+extern bool operator== (Crop const & a, Crop const & b);
+extern bool operator!= (Crop const & a, Crop const & b);
+
 struct Position
 {
        Position ()
index ce2b02211520edcffa4d7fc1b8defa7f0f8d0c1e..f0fc4f68f3db51e769520f7c9eca6f38e65c0e19 100644 (file)
@@ -224,7 +224,7 @@ FilmEditor::left_crop_changed (wxCommandEvent &)
                return;
        }
 
-       _ignore_changes = Film::LEFT_CROP;
+       _ignore_changes = Film::CROP;
        _film->set_left_crop (_left_crop->GetValue ());
        _ignore_changes = Film::NONE;
 }
@@ -237,7 +237,7 @@ FilmEditor::right_crop_changed (wxCommandEvent &)
                return;
        }
 
-       _ignore_changes = Film::RIGHT_CROP;
+       _ignore_changes = Film::CROP;
        _film->set_right_crop (_right_crop->GetValue ());
        _ignore_changes = Film::NONE;
 }
@@ -250,7 +250,7 @@ FilmEditor::top_crop_changed (wxCommandEvent &)
                return;
        }
 
-       _ignore_changes = Film::TOP_CROP;
+       _ignore_changes = Film::CROP;
        _film->set_top_crop (_top_crop->GetValue ());
        _ignore_changes = Film::NONE;
 }
@@ -263,7 +263,7 @@ FilmEditor::bottom_crop_changed (wxCommandEvent &)
                return;
        }
 
-       _ignore_changes = Film::BOTTOM_CROP;
+       _ignore_changes = Film::CROP;
        _film->set_bottom_crop (_bottom_crop->GetValue ());
        _ignore_changes = Film::NONE;
 }
@@ -341,17 +341,11 @@ FilmEditor::film_changed (Film::Property p)
        case Film::FORMAT:
                _format->SetSelection (Format::as_index (_film->format ()));
                break;
-       case Film::LEFT_CROP:
-               _left_crop->SetValue (_film->left_crop ());
-               break;
-       case Film::RIGHT_CROP:
-               _right_crop->SetValue (_film->right_crop ());
-               break;
-       case Film::TOP_CROP:
-               _top_crop->SetValue (_film->top_crop ());
-               break;
-       case Film::BOTTOM_CROP:
-               _bottom_crop->SetValue (_film->bottom_crop ());
+       case Film::CROP:
+               _left_crop->SetValue (_film->crop().left);
+               _right_crop->SetValue (_film->crop().right);
+               _top_crop->SetValue (_film->crop().top);
+               _bottom_crop->SetValue (_film->crop().bottom);
                break;
        case Film::FILTERS:
        {
@@ -489,10 +483,7 @@ FilmEditor::set_film (Film* f)
        film_changed (Film::CONTENT);
        film_changed (Film::DCP_CONTENT_TYPE);
        film_changed (Film::FORMAT);
-       film_changed (Film::LEFT_CROP);
-       film_changed (Film::RIGHT_CROP);
-       film_changed (Film::TOP_CROP);
-       film_changed (Film::BOTTOM_CROP);
+       film_changed (Film::CROP);
        film_changed (Film::FILTERS);
        film_changed (Film::DCP_FRAMES);
        film_changed (Film::DCP_TRIM_ACTION);
index be2b93f7987608ffec9ce5cafbc8c498a1c0645b..f75efd72849cb69095af780d6de8073cc0e87203 100644 (file)
@@ -44,10 +44,6 @@ public:
                , _film (film)
                , _image (0)
                , _bitmap (0)
-               , _left_crop (0)
-               , _right_crop (0)
-               , _top_crop (0)
-               , _bottom_crop (0)
        {
        }
 
@@ -59,7 +55,12 @@ public:
                        _current_image = _pending_image;
                        setup ();
                }
-               
+
+               if (_current_crop != _pending_crop) {
+                       _current_crop = _pending_crop;
+                       setup ();
+               }
+
                wxPaintDC dc (this);
                if (_bitmap) {
                        dc.DrawBitmap (*_bitmap, 0, 0, false);
@@ -73,6 +74,7 @@ public:
                }
 
                setup ();
+               Refresh ();
        }
 
        void set (string f)
@@ -81,13 +83,10 @@ public:
                Refresh ();
        }
 
-       void set_crop (int l, int r, int t, int b)
+       void set_crop (Crop c)
        {
-               _left_crop = l;
-               _right_crop = r;
-               _top_crop = t;
-               _bottom_crop = b;
-               setup ();
+               _pending_crop = c;
+               Refresh ();
        }
 
        void set_film (Film* f)
@@ -95,8 +94,10 @@ public:
                _film = f;
                if (!_film) {
                        clear ();
+                       Refresh ();
                } else {
                        setup ();
+                       Refresh ();
                }
        }
 
@@ -124,7 +125,12 @@ private:
                float const target = _film->format() ? _film->format()->ratio_as_float () : 1.78;
 
                _cropped_image = _image->GetSubImage (
-                       wxRect (_left_crop, _top_crop, _image->GetWidth() - (_left_crop + _right_crop), _image->GetHeight() - (_top_crop + _bottom_crop))
+                       wxRect (
+                               _current_crop.left,
+                               _current_crop.top,
+                               _image->GetWidth() - (_current_crop.left + _current_crop.right),
+                               _image->GetHeight() - (_current_crop.top + _current_crop.bottom)
+                               )
                        );
 
                if ((float (vw) / vh) > target) {
@@ -137,8 +143,6 @@ private:
 
                delete _bitmap;
                _bitmap = new wxBitmap (_cropped_image);
-
-               Refresh ();
        }
 
        Film* _film;
@@ -147,10 +151,8 @@ private:
        std::string _pending_image;
        wxImage _cropped_image;
        wxBitmap* _bitmap;
-       int _left_crop;
-       int _right_crop;
-       int _top_crop;
-       int _bottom_crop;
+       Crop _current_crop;
+       Crop _pending_crop;
 };
 
 BEGIN_EVENT_TABLE (ThumbPanel, wxPanel)
@@ -203,8 +205,8 @@ FilmViewer::slider_changed (wxCommandEvent &)
 void
 FilmViewer::film_changed (Film::Property p)
 {
-       if (p == Film::LEFT_CROP || p == Film::RIGHT_CROP || p == Film::TOP_CROP || p == Film::BOTTOM_CROP) {
-               _thumb_panel->set_crop (_film->left_crop(), _film->right_crop(), _film->top_crop(), _film->bottom_crop ());
+       if (p == Film::CROP) {
+               _thumb_panel->set_crop (_film->crop ());
        } else if (p == Film::THUMBS) {
                if (_film && _film->num_thumbs() > 1) {
                        _slider->SetRange (0, _film->num_thumbs () - 1);
index d2e2620291e7a60de7bf1a0ef169aa07d9a039f9..f564a8f86cf10126076599c7d9cbc2c58cec287b 100644 (file)
@@ -78,10 +78,10 @@ BOOST_AUTO_TEST_CASE (film_metadata_test)
        BOOST_CHECK_EQUAL (g.name(), "fred");
        BOOST_CHECK_EQUAL (g.dcp_content_type(), DCPContentType::from_pretty_name ("Short"));
        BOOST_CHECK_EQUAL (g.format(), Format::from_nickname ("Flat"));
-       BOOST_CHECK_EQUAL (g.left_crop(), 1);
-       BOOST_CHECK_EQUAL (g.right_crop(), 2);
-       BOOST_CHECK_EQUAL (g.top_crop(), 3);
-       BOOST_CHECK_EQUAL (g.bottom_crop(), 4);
+       BOOST_CHECK_EQUAL (g.crop().left, 1);
+       BOOST_CHECK_EQUAL (g.crop().right, 2);
+       BOOST_CHECK_EQUAL (g.crop().top, 3);
+       BOOST_CHECK_EQUAL (g.crop().bottom, 4);
        vector<Filter const *> g_filters = g.filters ();
        BOOST_CHECK_EQUAL (g_filters.size(), 2);
        BOOST_CHECK_EQUAL (g_filters.front(), Filter::from_id ("pphb"));