summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-10-14 00:24:26 +0100
committerCarl Hetherington <cth@carlh.net>2012-10-14 00:24:26 +0100
commit01f91d3d743b1d9c5306e8817cfd926eddc61736 (patch)
tree849b17a202e81ed40f4016c3361aa5d35facab04
parent5ec4cafd9ed9966c0af6b3f33f78cc833950ee0c (diff)
Fix up tests; possibly working subtitle transforms.
-rw-r--r--src/lib/subtitle.cc36
-rw-r--r--src/lib/subtitle.h15
-rw-r--r--src/wx/film_viewer.cc67
-rw-r--r--test/metadata.ref4
-rw-r--r--test/test.cc20
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);