Fix up tests; possibly working subtitle transforms.
authorCarl Hetherington <cth@carlh.net>
Sat, 13 Oct 2012 23:24:26 +0000 (00:24 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 13 Oct 2012 23:24:26 +0000 (00:24 +0100)
src/lib/subtitle.cc
src/lib/subtitle.h
src/wx/film_viewer.cc
test/metadata.ref
test/test.cc

index 18dded02c9080a69ca730ea036fe773b0734d42c..3559197a04b9e77f22f93d3ccfc762cf8feb22a1 100644 (file)
@@ -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;
+}
index 18d2590ebf62c6617f377e43bff36ee2e6133baa..fcb6bc70c210074809577bd6e7f2b9446fa383fd 100644 (file)
@@ -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:
index fb7317dc6691ae2d30f3da1bc60e2b5e3ce80856..725ba57de069e699d2403cda136fe38d97df651f 100644 (file)
@@ -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;
        };
 
index 817fecffdd6ede790a6b83b9fc6924efa56ea475..c24b77de89a4d1279a34e76e3f2776e8175f016a 100644 (file)
@@ -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
index b14935da3816709d669e4ec482d6100aef64d7d9..5a7625dd7c5b05a6bf7c2624e3fe996812517677 100644 (file)
@@ -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);