diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-10-14 00:24:26 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-10-14 00:24:26 +0100 |
| commit | 01f91d3d743b1d9c5306e8817cfd926eddc61736 (patch) | |
| tree | 849b17a202e81ed40f4016c3361aa5d35facab04 | |
| parent | 5ec4cafd9ed9966c0af6b3f33f78cc833950ee0c (diff) | |
Fix up tests; possibly working subtitle transforms.
| -rw-r--r-- | src/lib/subtitle.cc | 36 | ||||
| -rw-r--r-- | src/lib/subtitle.h | 15 | ||||
| -rw-r--r-- | src/wx/film_viewer.cc | 67 | ||||
| -rw-r--r-- | test/metadata.ref | 4 | ||||
| -rw-r--r-- | test/test.cc | 20 |
5 files changed, 86 insertions, 56 deletions
diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index 18dded02c..3559197a0 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -20,6 +20,7 @@ #include "subtitle.h" #include "image.h" #include "exceptions.h" +#include "film_state.h" using namespace std; using namespace boost; @@ -68,3 +69,38 @@ SubtitleImage::SubtitleImage (AVSubtitleRect const * rect) sub_p += rect->pict.linesize[0]; } } + +SubtitleTransform +subtitle_transform ( + int target_base_width, int target_base_height, + float target_x_scale, float target_y_scale, + Position sub_pos, int sub_width, int sub_height, + shared_ptr<FilmState> fs + ) +{ + SubtitleTransform tx; + + Rectangle sub_area (sub_pos.x, sub_pos.y + fs->subtitle_offset, sub_width, sub_height); + + Rectangle cropped_target_area ( + fs->crop.left, + fs->crop.top, + target_base_width - (fs->crop.left + fs->crop.right), + target_base_height - (fs->crop.top + fs->crop.bottom) + ); + + Rectangle cropped_sub_area = sub_area.intersection (cropped_target_area); + + tx.crop.x = cropped_sub_area.x - sub_area.x; + tx.crop.y = cropped_sub_area.y - sub_area.y; + tx.crop.w = cropped_sub_area.w; + tx.crop.h = cropped_sub_area.h; + + tx.transformed.w = cropped_sub_area.w * target_x_scale * fs->subtitle_scale; + tx.transformed.h = cropped_sub_area.h * target_y_scale * fs->subtitle_scale; + + tx.transformed.x = target_x_scale * ((sub_area.x - fs->crop.left) + (cropped_sub_area.w * (1 - fs->subtitle_scale) / 2)); + tx.transformed.y = target_y_scale * ((sub_area.y - fs->crop.top) + (cropped_sub_area.h * (1 - fs->subtitle_scale) / 2)); + + return tx; +} diff --git a/src/lib/subtitle.h b/src/lib/subtitle.h index 18d2590eb..fcb6bc70c 100644 --- a/src/lib/subtitle.h +++ b/src/lib/subtitle.h @@ -24,6 +24,7 @@ struct AVSubtitle; class SubtitleImage; class SimpleImage; +class FilmState; class Subtitle { @@ -44,6 +45,20 @@ private: std::list<boost::shared_ptr<SubtitleImage> > _images; }; +struct SubtitleTransform +{ +public: + Rectangle crop; + Rectangle transformed; +}; + +extern SubtitleTransform subtitle_transform ( + int target_base_width, int target_base_height, + float target_x_scale, float target_y_scale, + Position sub_pos, int sub_width, int sub_height, + boost::shared_ptr<FilmState> fs + ); + class SubtitleImage { public: diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index fb7317dc6..725ba57de 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -30,6 +30,7 @@ #include "lib/job_manager.h" #include "lib/film_state.h" #include "lib/options.h" +#include "lib/subtitle.h" #include "film_viewer.h" #include "wx_util.h" @@ -81,7 +82,7 @@ public: if (_film->with_subtitles ()) { for (list<SubtitleView>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { - dc.DrawBitmap (*i->bitmap, i->cropped_position.x, i->cropped_position.y, true); + dc.DrawBitmap (*i->bitmap, i->transformed_position.x, i->transformed_position.y, true); } } } @@ -146,7 +147,7 @@ private: GetSize (&vw, &vh); /* Cropped rectangle */ - Rectangle cropped ( + Rectangle cropped_area ( _film->crop().left, _film->crop().top, _image->GetWidth() - (_film->crop().left + _film->crop().right), @@ -156,56 +157,44 @@ private: /* Target ratio */ float const target = _film->format() ? _film->format()->ratio_as_float (_film) : 1.78; - _cropped_image = _image->GetSubImage (wxRect (cropped.x, cropped.y, cropped.w, cropped.h)); + _transformed_image = _image->GetSubImage (wxRect (cropped_area.x, cropped_area.y, cropped_area.w, cropped_area.h)); float x_scale = 1; float y_scale = 1; if ((float (vw) / vh) > target) { /* view is longer (horizontally) than the ratio; fit height */ - _cropped_image.Rescale (vh * target, vh, wxIMAGE_QUALITY_HIGH); - x_scale = vh * target / cropped.w; - y_scale = float (vh) / cropped.h; + _transformed_image.Rescale (vh * target, vh, wxIMAGE_QUALITY_HIGH); + x_scale = vh * target / cropped_area.w; + y_scale = float (vh) / cropped_area.h; } else { /* view is shorter (horizontally) than the ratio; fit width */ - _cropped_image.Rescale (vw, vw / target, wxIMAGE_QUALITY_HIGH); - x_scale = float (vw) / cropped.w; - y_scale = (vw / target) / cropped.h; + _transformed_image.Rescale (vw, vw / target, wxIMAGE_QUALITY_HIGH); + x_scale = float (vw) / cropped_area.w; + y_scale = (vw / target) / cropped_area.h; } - _bitmap.reset (new wxBitmap (_cropped_image)); + _bitmap.reset (new wxBitmap (_transformed_image)); for (list<SubtitleView>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { - /* Area of the subtitle graphic within the (uncropped) picture frame */ - Rectangle sub_rect (i->position.x, i->position.y + _film->subtitle_offset(), i->image.GetWidth(), i->image.GetHeight()); - /* Hence the subtitle graphic after it has been cropped */ - Rectangle cropped_sub_rect = sub_rect.intersection (cropped); - - /* Get the cropped version of the subtitle image */ - i->cropped_image = i->image.GetSubImage ( - wxRect ( - cropped_sub_rect.x - sub_rect.x, - cropped_sub_rect.y - sub_rect.y, - cropped_sub_rect.w, - cropped_sub_rect.h - ) + SubtitleTransform tx = subtitle_transform ( + _image->GetWidth(), _image->GetHeight(), + x_scale, y_scale, + i->base_position, i->base_image.GetWidth(), i->base_image.GetHeight(), + _film->state_copy() ); - i->cropped_image.Rescale (cropped_sub_rect.w * x_scale, cropped_sub_rect.h * y_scale, wxIMAGE_QUALITY_HIGH); - - i->cropped_position = Position ( - cropped_sub_rect.x * x_scale, - (cropped_sub_rect.y - _film->crop().top) * y_scale - ); - - i->bitmap.reset (new wxBitmap (i->cropped_image)); + i->transformed_image = i->base_image.GetSubImage (wxRect (tx.crop.x, tx.crop.y, tx.crop.w, tx.crop.h)); + i->transformed_image.Rescale (tx.transformed.w, tx.transformed.h, wxIMAGE_QUALITY_HIGH); + i->transformed_position = Position (tx.transformed.x, tx.transformed.y); + i->bitmap.reset (new wxBitmap (i->transformed_image)); } } Film* _film; shared_ptr<wxImage> _image; - wxImage _cropped_image; + wxImage _transformed_image; /** currently-displayed thumbnail index */ int _index; shared_ptr<wxBitmap> _bitmap; @@ -215,14 +204,14 @@ private: struct SubtitleView { SubtitleView (Position p, wxString const & i) - : position (p) - , image (i) + : base_position (p) + , base_image (i) {} - - Position position; - wxImage image; - Position cropped_position; - wxImage cropped_image; + + Position base_position; + Position transformed_position; + wxImage base_image; + wxImage transformed_image; shared_ptr<wxBitmap> bitmap; }; diff --git a/test/metadata.ref b/test/metadata.ref index 817fecffd..c24b77de8 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -16,6 +16,9 @@ dcp_ab 1 audio_gain 0 audio_delay 0 still_duration 10 +with_subtitles 0 +subtitle_offset 0 +subtitle_scale 1 width 0 height 0 length 0 @@ -23,3 +26,4 @@ audio_channels 0 audio_sample_rate 0 audio_sample_format Unknown content_digest +has_subtitles 0 diff --git a/test/test.cc b/test/test.cc index b14935da3..5a7625dd7 100644 --- a/test/test.cc +++ b/test/test.cc @@ -36,6 +36,7 @@ #include "server.h" #include "cross.h" #include "job.h" +#include "subtitle.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dvdomatic_test #include <boost/test/unit_test.hpp> @@ -248,7 +249,7 @@ BOOST_AUTO_TEST_CASE (paths_test) FilmState s; s.directory = "build/test/a/b/c/d/e"; s.thumbs.push_back (42); - BOOST_CHECK_EQUAL (s.thumb_file (0), "build/test/a/b/c/d/e/thumbs/00000042.tiff"); + BOOST_CHECK_EQUAL (s.thumb_file (0), "build/test/a/b/c/d/e/thumbs/00000042.png"); s.content = "/foo/bar/baz"; BOOST_CHECK_EQUAL (s.content_path(), "/foo/bar/baz"); @@ -438,24 +439,9 @@ BOOST_AUTO_TEST_CASE (job_manager_test) dvdomatic_sleep (2); BOOST_CHECK_EQUAL (a->finished_ok(), true); - /* Two jobs, no dependency */ - a.reset (new TestJob (s, o, &log, shared_ptr<Job> ())); - shared_ptr<TestJob> b (new TestJob (s, o, &log, shared_ptr<Job> ())); - - JobManager::instance()->add (a); - JobManager::instance()->add (b); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->running (), true); - BOOST_CHECK_EQUAL (b->running (), true); - a->set_finished_ok (); - b->set_finished_ok (); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->finished_ok (), true); - BOOST_CHECK_EQUAL (b->finished_ok (), true); - /* Two jobs, dependency */ a.reset (new TestJob (s, o, &log, shared_ptr<Job> ())); - b.reset (new TestJob (s, o, &log, a)); + shared_ptr<TestJob> b (new TestJob (s, o, &log, a)); JobManager::instance()->add (a); JobManager::instance()->add (b); |
