From 5f02ea34590cd6b796a6eaa55211abf5b36fd329 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 8 Oct 2012 15:37:04 +0100 Subject: Hacks. --- src/lib/util.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/lib/util.h') diff --git a/src/lib/util.h b/src/lib/util.h index 3eac06e97..ed13cd43c 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -165,4 +165,20 @@ private: int _buffer_data; }; +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + #endif -- cgit v1.2.3 From ed70b4faf0f53b106aebd4b9195ccc81da97880e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Oct 2012 20:35:05 +0100 Subject: Thumbs sort of have subs. --- src/lib/film.cc | 45 +++++++++++++++++++ src/lib/film.h | 1 + src/lib/film_state.cc | 14 +++++- src/lib/film_state.h | 2 + src/lib/util.cc | 13 ++++++ src/lib/util.h | 25 +++++++++++ src/wx/film_viewer.cc | 122 ++++++++++++++++++++++++++++++++++++++------------ 7 files changed, 193 insertions(+), 29 deletions(-) (limited to 'src/lib/util.h') diff --git a/src/lib/film.cc b/src/lib/film.cc index 95dc7b825..1e23c4d6b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "film.h" #include "format.h" #include "tiff_encoder.h" @@ -668,3 +669,47 @@ Film::set_with_subtitles (bool w) _state.with_subtitles = w; signal_changed (WITH_SUBTITLES); } + +list > +Film::thumb_subtitles (int n) const +{ + string sub_file = _state.thumb_base(n) + ".sub"; + if (!filesystem::exists (sub_file)) { + return list > (); + } + + ifstream f (sub_file.c_str ()); + string line; + + int sub_number; + int sub_x; + list > subs; + + while (getline (f, line)) { + if (line.empty ()) { + continue; + } + + if (line[line.size() - 1] == '\r') { + line = line.substr (0, line.size() - 1); + } + + size_t const s = line.find (' '); + if (s == string::npos) { + continue; + } + + string const k = line.substr (0, s); + int const v = lexical_cast (line.substr(s + 1)); + + if (k == "image") { + sub_number = v; + } else if (k == "x") { + sub_x = v; + } else if (k == "y") { + subs.push_back (make_pair (Position (sub_x, v), String::compose ("%1.sub.%2.tiff", _state.thumb_base(n), sub_number))); + } + } + + return subs; +} diff --git a/src/lib/film.h b/src/lib/film.h index 919cecc22..1e01747a2 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -193,6 +193,7 @@ public: int num_thumbs () const; int thumb_frame (int) const; std::string thumb_file (int) const; + std::list > thumb_subtitles (int) const; void copy_from_dvd_post_gui (); void examine_content (); diff --git a/src/lib/film_state.cc b/src/lib/film_state.cc index 03d4cae83..2847ea513 100644 --- a/src/lib/film_state.cc +++ b/src/lib/film_state.cc @@ -190,10 +190,22 @@ FilmState::thumb_file (int n) const */ string FilmState::thumb_file_for_frame (int n) const +{ + return thumb_base_for_frame(n) + ".tiff"; +} + +string +FilmState::thumb_base (int n) const +{ + return thumb_base_for_frame (thumb_frame (n)); +} + +string +FilmState::thumb_base_for_frame (int n) const { stringstream s; s.width (8); - s << setfill('0') << n << ".tiff"; + s << setfill('0') << n; filesystem::path p; p /= dir ("thumbs"); diff --git a/src/lib/film_state.h b/src/lib/film_state.h index 2b792694c..5b3ef8367 100644 --- a/src/lib/film_state.h +++ b/src/lib/film_state.h @@ -79,6 +79,7 @@ public: bool content_is_dvd () const; std::string thumb_file (int) const; + std::string thumb_base (int) const; int thumb_frame (int) const; int bytes_per_sample () const; @@ -151,6 +152,7 @@ public: private: std::string thumb_file_for_frame (int) const; + std::string thumb_base_for_frame (int) const; }; #endif diff --git a/src/lib/util.cc b/src/lib/util.cc index 935566440..82aaf8ff5 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -600,3 +600,16 @@ Socket::read_indefinite (uint8_t* data, int size, int timeout) assert (size >= _buffer_data); memcpy (data, _buffer, size); } + +Rectangle +Rectangle::intersection (Rectangle const & other) const +{ + int const tx = max (x, other.x); + int const ty = max (y, other.y); + + return Rectangle ( + tx, ty, + min (x + w, other.x + other.w) - tx, + min (y + h, other.y + other.h) - ty + ); +} diff --git a/src/lib/util.h b/src/lib/util.h index ed13cd43c..e1ad7fd64 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -121,6 +121,31 @@ struct Position int y; }; +/** A rectangle */ +struct Rectangle +{ + Rectangle () + : x (0) + , y (0) + , w (0) + , h (0) + {} + + Rectangle (int x_, int y_, int w_, int h_) + : x (x_) + , y (y_) + , w (w_) + , h (h_) + {} + + int x; + int y; + int w; + int h; + + Rectangle intersection (Rectangle const & other) const; +}; + extern std::string crop_string (Position, Size); extern int dcp_audio_sample_rate (int); extern std::string colour_lut_index_to_name (int index); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 6ffe4e66a..8c298ea57 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -42,18 +42,24 @@ public: ThumbPanel (wxPanel* parent, Film* film) : wxPanel (parent) , _film (film) - , _image (0) - , _bitmap (0) { } /** Handle a paint event */ void paint_event (wxPaintEvent& ev) { - if (_current_image != _pending_image) { - delete _image; - _image = new wxImage (std_to_wx (_pending_image)); - _current_image = _pending_image; + if (_current_index != _pending_index) { + _image.reset (new wxImage (std_to_wx (_film->thumb_file (_pending_index)))); + _current_index = _pending_index; + + _subtitles.clear (); + + cout << "=== SUBS for " << _film->thumb_frame (_pending_index) << "\n"; + list > s = _film->thumb_subtitles (_pending_index); + for (list >::iterator i = s.begin(); i != s.end(); ++i) { + _subtitles.push_back (SubtitleView (i->first, std_to_wx (i->second))); + } + setup (); } @@ -64,8 +70,14 @@ public: wxPaintDC dc (this); if (_bitmap) { + cout << "frame bm " << _bitmap->GetWidth() << " " << _bitmap->GetHeight() << "\n"; dc.DrawBitmap (*_bitmap, 0, 0, false); } + + for (list::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + dc.DrawBitmap (*i->bitmap, i->position.x, i->position.y, true); + cout << "\tsub bm at " << i->position.x << " " << i->position.y << " size " << i->bitmap->GetWidth() << " by " << i->bitmap->GetHeight() << "\n"; + } } /** Handle a size event */ @@ -79,9 +91,10 @@ public: Refresh (); } - void set (string f) + /** @param n Thumbnail index */ + void set (int n) { - _pending_image = f; + _pending_index = n; Refresh (); } @@ -106,10 +119,9 @@ public: /** Clear our thumbnail image */ void clear () { - delete _bitmap; - _bitmap = 0; - delete _image; - _image = 0; + _bitmap.reset (); + _image.reset (); + _subtitles.clear (); } void refresh () @@ -127,41 +139,95 @@ private: if (!_film || !_image) { return; } - + + /* Size of the view */ int vw, vh; GetSize (&vw, &vh); + /* Cropped rectangle */ + Rectangle cropped ( + _current_crop.left, + _current_crop.top, + _image->GetWidth() - (_current_crop.left + _current_crop.right), + _image->GetHeight() - (_current_crop.top + _current_crop.bottom) + ); + + /* Target ratio */ float const target = _film->format() ? _film->format()->ratio_as_float (_film) : 1.78; - _cropped_image = _image->GetSubImage ( - wxRect ( - _current_crop.left, - _current_crop.top, - _image->GetWidth() - (_current_crop.left + _current_crop.right), - _image->GetHeight() - (_current_crop.top + _current_crop.bottom) - ) - ); + _cropped_image = _image->GetSubImage (wxRect (cropped.x, cropped.y, cropped.w, cropped.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 / _image->GetWidth (); + y_scale = float (vh) / _image->GetHeight (); } else { /* view is shorter (horizontally) than the ratio; fit width */ _cropped_image.Rescale (vw, vw / target, wxIMAGE_QUALITY_HIGH); + x_scale = float (vw) / _image->GetWidth (); + y_scale = (vw / target) / _image->GetHeight (); } - delete _bitmap; - _bitmap = new wxBitmap (_cropped_image); + _bitmap.reset (new wxBitmap (_cropped_image)); + + for (list::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + Rectangle sub_rect (i->position.x, i->position.y, i->image.GetWidth(), i->image.GetHeight()); + Rectangle cropped_sub_rect = sub_rect.intersection (cropped); + + cout << "sub " << sub_rect.x << " " << sub_rect.y << " " << sub_rect.w << " " << sub_rect.h << "\n"; + cout << "cropped " << cropped_sub_rect.x << " " << cropped_sub_rect.y << " " << cropped_sub_rect.w << " " << cropped_sub_rect.h << "\n"; + + 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 + ) + ); + + i->cropped_image.Rescale (cropped_sub_rect.w * x_scale, cropped_sub_rect.h * y_scale, wxIMAGE_QUALITY_HIGH); + + i->position = Position ( + cropped_sub_rect.x * x_scale, + cropped_sub_rect.y * y_scale + ); + + cout << "scales are " << x_scale << " " << y_scale << "\n"; + cout << "scaled to " << (cropped_sub_rect.w * x_scale) << " " << (cropped_sub_rect.h * y_scale) << "\n"; + + i->bitmap.reset (new wxBitmap (i->cropped_image)); + } } Film* _film; - wxImage* _image; - std::string _current_image; - std::string _pending_image; + shared_ptr _image; wxImage _cropped_image; - wxBitmap* _bitmap; + /** currently-displayed thumbnail index */ + int _current_index; + int _pending_index; + shared_ptr _bitmap; Crop _current_crop; Crop _pending_crop; + + struct SubtitleView + { + SubtitleView (Position p, wxString const & i) + : position (p) + , image (i) + {} + + Position position; + wxImage image; + wxImage cropped_image; + shared_ptr bitmap; + }; + + list _subtitles; }; BEGIN_EVENT_TABLE (ThumbPanel, wxPanel) @@ -196,7 +262,7 @@ FilmViewer::set_thumbnail (int n) return; } - _thumb_panel->set (_film->thumb_file(n)); + _thumb_panel->set (n); } void -- cgit v1.2.3 From 49f9cb10018bf4ec07a60d1599cbe62d735baa23 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Oct 2012 18:58:50 +0100 Subject: Remove unused code. --- src/lib/util.h | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'src/lib/util.h') diff --git a/src/lib/util.h b/src/lib/util.h index e1ad7fd64..66c052c48 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -190,20 +190,4 @@ private: int _buffer_data; }; -#define SCALEBITS 10 -#define ONE_HALF (1 << (SCALEBITS - 1)) -#define FIX(x) ((int) ((x) * (1<> SCALEBITS) - -#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ -(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ - FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) - -#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ -(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ - FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) - #endif -- cgit v1.2.3 From 129afab72bfc026b5704c41a6bfc0f4b3a2c4033 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Oct 2012 20:29:20 +0100 Subject: Round image line sizes up to 32. Seems to help with LHS image corruption with both crop and a post-processing filter. --- src/lib/dcp_video_frame.cc | 58 ++++++++++++++++++++++++++++------------------ src/lib/filter.cc | 1 + src/lib/image.cc | 10 ++++---- src/lib/util.cc | 7 ++++++ src/lib/util.h | 1 + 5 files changed, 49 insertions(+), 28 deletions(-) (limited to 'src/lib/util.h') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index ce660add5..3e5c4b3aa 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -176,8 +176,6 @@ DCPVideoFrame::encode_locally () create_openjpeg_container (); - int const size = _out_size.width * _out_size.height; - struct { double r, g, b; } s; @@ -188,27 +186,41 @@ DCPVideoFrame::encode_locally () /* Copy our RGB into the openjpeg container, converting to XYZ in the process */ - uint8_t* p = prepared->data()[0]; - for (int i = 0; i < size; ++i) { - /* In gamma LUT (converting 8-bit input to 12-bit) */ - s.r = lut_in[_colour_lut_index][*p++ << 4]; - s.g = lut_in[_colour_lut_index][*p++ << 4]; - s.b = lut_in[_colour_lut_index][*p++ << 4]; - - /* RGB to XYZ Matrix */ - d.x = ((s.r * color_matrix[_colour_lut_index][0][0]) + (s.g * color_matrix[_colour_lut_index][0][1]) + (s.b * color_matrix[_colour_lut_index][0][2])); - d.y = ((s.r * color_matrix[_colour_lut_index][1][0]) + (s.g * color_matrix[_colour_lut_index][1][1]) + (s.b * color_matrix[_colour_lut_index][1][2])); - d.z = ((s.r * color_matrix[_colour_lut_index][2][0]) + (s.g * color_matrix[_colour_lut_index][2][1]) + (s.b * color_matrix[_colour_lut_index][2][2])); - - /* DCI companding */ - d.x = d.x * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); - d.y = d.y * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); - d.z = d.z * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); - - /* Out gamma LUT */ - _image->comps[0].data[i] = lut_out[LO_DCI][(int) d.x]; - _image->comps[1].data[i] = lut_out[LO_DCI][(int) d.y]; - _image->comps[2].data[i] = lut_out[LO_DCI][(int) d.z]; + int jn = 0; + for (int y = 0; y < _out_size.height; ++y) { + uint8_t* p = prepared->data()[0] + y * prepared->line_size()[0]; + for (int x = 0; x < _out_size.width; ++x) { + + /* In gamma LUT (converting 8-bit input to 12-bit) */ + s.r = lut_in[_colour_lut_index][*p++ << 4]; + s.g = lut_in[_colour_lut_index][*p++ << 4]; + s.b = lut_in[_colour_lut_index][*p++ << 4]; + + /* RGB to XYZ Matrix */ + d.x = ((s.r * color_matrix[_colour_lut_index][0][0]) + + (s.g * color_matrix[_colour_lut_index][0][1]) + + (s.b * color_matrix[_colour_lut_index][0][2])); + + d.y = ((s.r * color_matrix[_colour_lut_index][1][0]) + + (s.g * color_matrix[_colour_lut_index][1][1]) + + (s.b * color_matrix[_colour_lut_index][1][2])); + + d.z = ((s.r * color_matrix[_colour_lut_index][2][0]) + + (s.g * color_matrix[_colour_lut_index][2][1]) + + (s.b * color_matrix[_colour_lut_index][2][2])); + + /* DCI companding */ + d.x = d.x * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); + d.y = d.y * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); + d.z = d.z * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); + + /* Out gamma LUT */ + _image->comps[0].data[jn] = lut_out[LO_DCI][(int) d.x]; + _image->comps[1].data[jn] = lut_out[LO_DCI][(int) d.y]; + _image->comps[2].data[jn] = lut_out[LO_DCI][(int) d.z]; + + ++jn; + } } /* Set the max image and component sizes based on frame_rate */ diff --git a/src/lib/filter.cc b/src/lib/filter.cc index ab5a6316f..446cc111d 100644 --- a/src/lib/filter.cc +++ b/src/lib/filter.cc @@ -72,6 +72,7 @@ Filter::setup_filters () _filters.push_back (new Filter ("ppl5", "FIR low-pass deinterlacer", "", "l5")); _filters.push_back (new Filter ("mcdeint", "Motion compensating deinterlacer", "mcdeint", "")); _filters.push_back (new Filter ("kerndeint", "Kernel deinterlacer", "kerndeint", "")); + _filters.push_back (new Filter ("yadif", "Yet Another Deinterlacing Filter", "yadif", "")); _filters.push_back (new Filter ("pptn", "Temporal noise reducer", "", "tn")); _filters.push_back (new Filter ("ppfq", "Force quantizer", "", "fq")); _filters.push_back (new Filter ("gradfun", "Gradient debander", "gradfun", "")); diff --git a/src/lib/image.cc b/src/lib/image.cc index ce44ec95b..c8849303c 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -260,15 +260,15 @@ SimpleImage::SimpleImage (PixelFormat p, Size s) switch (p) { case PIX_FMT_RGB24: - _line_size[0] = s.width * 3; + _line_size[0] = round_up (s.width * 3, 32); break; case PIX_FMT_RGBA: - _line_size[0] = s.width * 4; + _line_size[0] = round_up (s.width * 4, 32); break; case PIX_FMT_YUV420P: - _line_size[0] = s.width; - _line_size[1] = s.width / 2; - _line_size[2] = s.width / 2; + _line_size[0] = round_up (s.width, 32); + _line_size[1] = round_up (s.width / 2, 32); + _line_size[2] = round_up (s.width / 2, 32); break; default: assert (false); diff --git a/src/lib/util.cc b/src/lib/util.cc index 82aaf8ff5..c3dd13d7c 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -613,3 +613,10 @@ Rectangle::intersection (Rectangle const & other) const min (y + h, other.y + other.h) - ty ); } + +int +round_up (int a, int t) +{ + a += (t - 1); + return a - (a % t); +} diff --git a/src/lib/util.h b/src/lib/util.h index 66c052c48..244c01855 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -149,6 +149,7 @@ struct Rectangle extern std::string crop_string (Position, Size); extern int dcp_audio_sample_rate (int); extern std::string colour_lut_index_to_name (int index); +extern int round_up (int, int); /** @class Socket * @brief A class to wrap a boost::asio::ip::tcp::socket with some things -- cgit v1.2.3