From a963d1eb2919bf7bfb1f9d9785f940d375761d1b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 30 Jan 2024 19:31:13 +0100 Subject: Open macOS prefs with Mac-, not Mac-P (#2745). --- src/tools/dcpomatic.cc | 2 +- src/tools/dcpomatic_batch.cc | 2 +- src/tools/dcpomatic_kdm.cc | 2 +- src/tools/dcpomatic_player.cc | 2 +- src/tools/dcpomatic_playlist.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 6635cdb82..6e374d4ae 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -1344,7 +1344,7 @@ private: add_item (edit, _("Select all\tShift-Ctrl-A"), ID_edit_select_all, NEEDS_FILM); #ifdef __WXOSX__ - add_item (_file_menu, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS); + add_item(_file_menu, _("&Preferences...\tCtrl-,"), wxID_PREFERENCES, ALWAYS); #else edit->AppendSeparator (); /* [Shortcut] Ctrl+P:Open preferences window */ diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc index 6a0e46cf8..e476c2163 100644 --- a/src/tools/dcpomatic_batch.cc +++ b/src/tools/dcpomatic_batch.cc @@ -90,7 +90,7 @@ setup_menu (wxMenuBar* m) #endif #ifdef DCPOMATIC_OSX - file->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); + file->Append(wxID_PREFERENCES, _("&Preferences...\tCtrl-,")); #else auto edit = new wxMenu; edit->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 775349d54..9adef0ab0 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -294,7 +294,7 @@ private: #endif #ifdef __WXOSX__ - file->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); + file->Append(wxID_PREFERENCES, _("&Preferences...\tCtrl-,")); #else wxMenu* edit = new wxMenu; edit->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc index feac2a915..9c7522bc5 100644 --- a/src/tools/dcpomatic_player.cc +++ b/src/tools/dcpomatic_player.cc @@ -575,7 +575,7 @@ private: #endif #ifdef __WXOSX__ - auto prefs = _file_menu->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); + auto prefs = _file_menu->Append(wxID_PREFERENCES, _("&Preferences...\tCtrl-,")); #else auto edit = new wxMenu; auto prefs = edit->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); diff --git a/src/tools/dcpomatic_playlist.cc b/src/tools/dcpomatic_playlist.cc index e2f2536db..a373d81e6 100644 --- a/src/tools/dcpomatic_playlist.cc +++ b/src/tools/dcpomatic_playlist.cc @@ -569,7 +569,7 @@ private: { auto file = new wxMenu; #ifdef __WXOSX__ - file->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); + file->Append(wxID_PREFERENCES, _("&Preferences...\tCtrl-,")); file->Append (wxID_EXIT, _("&Exit")); #else file->Append (wxID_EXIT, _("&Quit")); -- cgit v1.2.3 From 6a35581ef83d48a799208081bcf006de895ddfb4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 1 Feb 2024 01:03:13 +0100 Subject: Add some more space for macOS preferences icons. --- src/wx/full_config_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/full_config_dialog.cc b/src/wx/full_config_dialog.cc index 77f173d7c..4c26d038c 100644 --- a/src/wx/full_config_dialog.cc +++ b/src/wx/full_config_dialog.cc @@ -1935,7 +1935,7 @@ create_full_config_dialog () the containing window doesn't shrink too much when we select those panels. This is obviously an unpleasant hack. */ - wxSize ps = wxSize (750, -1); + wxSize ps = wxSize(900, -1); int const border = 16; #else wxSize ps = wxSize (-1, -1); -- cgit v1.2.3 From a3a0e7a567b73dac9ba29a1ab28e58757cc21411 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 1 Feb 2024 12:28:39 +0100 Subject: Fix error when opening the right-click content menu. --- src/wx/content_menu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/content_menu.cc b/src/wx/content_menu.cc index 78b6469a0..700683bd2 100644 --- a/src/wx/content_menu.cc +++ b/src/wx/content_menu.cc @@ -137,7 +137,7 @@ ContentMenu::popup (weak_ptr film, ContentList c, TimelineContentViewList _views = v; int const N = _cpl_menu->GetMenuItemCount(); - for (int i = 1; i <= N; ++i) { + for (int i = DCPOMATIC_CPL_MENU; i < DCPOMATIC_CPL_MENU + N; ++i) { _cpl_menu->Delete (i); } -- cgit v1.2.3 From ace4d751495a5284585f7877a79d9f69e70e3c95 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Jan 2024 11:31:30 +0100 Subject: Separate out OtherParams into Other{RGB,YUV}Params. --- src/lib/image.cc | 78 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 2588d9f21..c6e7b418c 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -642,7 +642,8 @@ struct TargetParams }; -struct OtherParams +/** Parameters of the other image (the one being blended onto the target) when target and other are RGB */ +struct OtherRGBParams { int start_x; int start_y; @@ -661,9 +662,20 @@ struct OtherParams }; +/** Parameters of the other image (the one being blended onto the target) when target and other are YUV */ +struct OtherYUVParams +{ + int start_x; + int start_y; + dcp::Size size; + uint8_t* const* data; + int const* stride; +}; + + template void -alpha_blend_onto_rgb24(TargetParams const& target, OtherParams const& other, int red, int blue, std::function get, int value_divisor) +alpha_blend_onto_rgb24(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function get, int value_divisor) { /* Going onto RGB24. First byte is red, second green, third blue */ auto const alpha_divisor = other.alpha_divisor(); @@ -685,7 +697,7 @@ alpha_blend_onto_rgb24(TargetParams const& target, OtherParams const& other, int template void -alpha_blend_onto_bgra(TargetParams const& target, OtherParams const& other, int red, int blue, std::function get, int value_divisor) +alpha_blend_onto_bgra(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function get, int value_divisor) { auto const alpha_divisor = other.alpha_divisor(); for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) { @@ -707,7 +719,7 @@ alpha_blend_onto_bgra(TargetParams const& target, OtherParams const& other, int template void -alpha_blend_onto_rgba(TargetParams const& target, OtherParams const& other, int red, int blue, std::function get, int value_divisor) +alpha_blend_onto_rgba(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function get, int value_divisor) { auto const alpha_divisor = other.alpha_divisor(); for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) { @@ -729,7 +741,7 @@ alpha_blend_onto_rgba(TargetParams const& target, OtherParams const& other, int template void -alpha_blend_onto_rgb48le(TargetParams const& target, OtherParams const& other, int red, int blue, std::function get, int value_scale) +alpha_blend_onto_rgb48le(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function get, int value_scale) { auto const alpha_divisor = other.alpha_divisor(); for (int ty = target.start_y, oy = other.start_y; ty < target.size.height && oy < other.size.height; ++ty, ++oy) { @@ -750,7 +762,7 @@ alpha_blend_onto_rgb48le(TargetParams const& target, OtherParams const& other, i template void -alpha_blend_onto_xyz12le(TargetParams const& target, OtherParams const& other, int red, int blue, std::function get, int value_divisor) +alpha_blend_onto_xyz12le(TargetParams const& target, OtherRGBParams const& other, int red, int blue, std::function get, int value_divisor) { auto const alpha_divisor = other.alpha_divisor(); auto conv = dcp::ColourConversion::srgb_to_xyz(); @@ -788,7 +800,7 @@ alpha_blend_onto_xyz12le(TargetParams const& target, OtherParams const& other, i static void -alpha_blend_onto_yuv420p(TargetParams const& target, OtherParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) +alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) { auto const ts = target.size; auto const os = other.size; @@ -825,7 +837,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherParams const& other, u static void -alpha_blend_onto_yuv420p10(TargetParams const& target, OtherParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) +alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) { auto const ts = target.size; auto const os = other.size; @@ -862,7 +874,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherParams const& other, static void -alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) +alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) { auto const ts = target.size; auto const os = other.size; @@ -932,7 +944,7 @@ Image::alpha_blend (shared_ptr other, Position position) 0 }; - OtherParams other_params = { + OtherRGBParams other_rgb_params = { start_ox, start_oy, other->size(), @@ -941,6 +953,14 @@ Image::alpha_blend (shared_ptr other, Position position) other->pixel_format() == AV_PIX_FMT_RGBA64BE ? 8 : 4 }; + OtherYUVParams other_yuv_params = { + start_ox, + start_oy, + other->size(), + other->data(), + other->stride(), + }; + auto byteswap = [](uint16_t* p) { return (*p >> 8) | ((*p & 0xff) << 8); }; @@ -953,66 +973,66 @@ Image::alpha_blend (shared_ptr other, Position position) case AV_PIX_FMT_RGB24: target_params.bpp = 3; if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { - alpha_blend_onto_rgb24(target_params, other_params, red, blue, byteswap, 256); + alpha_blend_onto_rgb24(target_params, other_rgb_params, red, blue, byteswap, 256); } else { - alpha_blend_onto_rgb24(target_params, other_params, red, blue, pass, 1); + alpha_blend_onto_rgb24(target_params, other_rgb_params, red, blue, pass, 1); } break; case AV_PIX_FMT_BGRA: target_params.bpp = 4; if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { - alpha_blend_onto_bgra(target_params, other_params, red, blue, byteswap, 256); + alpha_blend_onto_bgra(target_params, other_rgb_params, red, blue, byteswap, 256); } else { - alpha_blend_onto_bgra(target_params, other_params, red, blue, pass, 1); + alpha_blend_onto_bgra(target_params, other_rgb_params, red, blue, pass, 1); } break; case AV_PIX_FMT_RGBA: target_params.bpp = 4; if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { - alpha_blend_onto_rgba(target_params, other_params, red, blue, byteswap, 256); + alpha_blend_onto_rgba(target_params, other_rgb_params, red, blue, byteswap, 256); } else { - alpha_blend_onto_rgba(target_params, other_params, red, blue, pass, 1); + alpha_blend_onto_rgba(target_params, other_rgb_params, red, blue, pass, 1); } break; case AV_PIX_FMT_RGB48LE: target_params.bpp = 6; if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { - alpha_blend_onto_rgb48le(target_params, other_params, red, blue, byteswap, 1); + alpha_blend_onto_rgb48le(target_params, other_rgb_params, red, blue, byteswap, 1); } else { - alpha_blend_onto_rgb48le(target_params, other_params, red, blue, pass, 256); + alpha_blend_onto_rgb48le(target_params, other_rgb_params, red, blue, pass, 256); } break; case AV_PIX_FMT_XYZ12LE: target_params.bpp = 6; if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { - alpha_blend_onto_xyz12le(target_params, other_params, red, blue, byteswap, 256); + alpha_blend_onto_xyz12le(target_params, other_rgb_params, red, blue, byteswap, 256); } else { - alpha_blend_onto_xyz12le(target_params, other_params, red, blue, pass, 1); + alpha_blend_onto_xyz12le(target_params, other_rgb_params, red, blue, pass, 1); } break; case AV_PIX_FMT_YUV420P: { auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); - other_params.data = yuv->data(); - other_params.stride = yuv->stride(); - alpha_blend_onto_yuv420p(target_params, other_params, other->data(), other->stride()); + other_yuv_params.data = yuv->data(); + other_yuv_params.stride = yuv->stride(); + alpha_blend_onto_yuv420p(target_params, other_yuv_params, other->data(), other->stride()); break; } case AV_PIX_FMT_YUV420P10: { auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); - other_params.data = yuv->data(); - other_params.stride = yuv->stride(); - alpha_blend_onto_yuv420p10(target_params, other_params, other->data(), other->stride()); + other_yuv_params.data = yuv->data(); + other_yuv_params.stride = yuv->stride(); + alpha_blend_onto_yuv420p10(target_params, other_yuv_params, other->data(), other->stride()); break; } case AV_PIX_FMT_YUV422P9LE: case AV_PIX_FMT_YUV422P10LE: { auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); - other_params.data = yuv->data(); - other_params.stride = yuv->stride(); - alpha_blend_onto_yuv422p9or10le(target_params, other_params, other->data(), other->stride()); + other_yuv_params.data = yuv->data(); + other_yuv_params.stride = yuv->stride(); + alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params, other->data(), other->stride()); break; } default: -- cgit v1.2.3 From 0403a4954ea84ace43c4248aae89af9a6384d7b2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Jan 2024 11:36:10 +0100 Subject: Put alpha_{data,stride} into OtherYUVParams. --- src/lib/image.cc | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index c6e7b418c..4042d5886 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -670,6 +670,9 @@ struct OtherYUVParams dcp::Size size; uint8_t* const* data; int const* stride; + + uint8_t* const* alpha_data; + int const* alpha_stride; }; @@ -800,7 +803,7 @@ alpha_blend_onto_xyz12le(TargetParams const& target, OtherRGBParams const& other static void -alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) +alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other) { auto const ts = target.size; auto const os = other.size; @@ -813,7 +816,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other uint8_t* oY = other.data[0] + (oy * other.stride[0]) + other.start_x; uint8_t* oU = other.data[1] + (hoy * other.stride[1]) + other.start_x / 2; uint8_t* oV = other.data[2] + (hoy * other.stride[2]) + other.start_x / 2; - uint8_t* alpha = alpha_data[0] + (oy * alpha_stride[0]) + other.start_x * 4; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { float const a = float(alpha[3]) / 255; *tY = *oY * a + *tY * (1 - a); @@ -837,7 +840,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other static void -alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) +alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other) { auto const ts = target.size; auto const os = other.size; @@ -850,7 +853,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& oth uint16_t* oY = reinterpret_cast(other.data[0] + (oy * other.stride[0])) + other.start_x; uint16_t* oU = reinterpret_cast(other.data[1] + (hoy * other.stride[1])) + other.start_x / 2; uint16_t* oV = reinterpret_cast(other.data[2] + (hoy * other.stride[2])) + other.start_x / 2; - uint8_t* alpha = alpha_data[0] + (oy * alpha_stride[0]) + other.start_x * 4; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { float const a = float(alpha[3]) / 255; *tY = *oY * a + *tY * (1 - a); @@ -874,7 +877,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& oth static void -alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other, uint8_t* const* alpha_data, int const* alpha_stride) +alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other) { auto const ts = target.size; auto const os = other.size; @@ -885,7 +888,7 @@ alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const uint16_t* oY = reinterpret_cast(other.data[0] + (oy * other.stride[0])) + other.start_x; uint16_t* oU = reinterpret_cast(other.data[1] + (oy * other.stride[1])) + other.start_x / 2; uint16_t* oV = reinterpret_cast(other.data[2] + (oy * other.stride[2])) + other.start_x / 2; - uint8_t* alpha = alpha_data[0] + (oy * alpha_stride[0]) + other.start_x * 4; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { float const a = float(alpha[3]) / 255; *tY = *oY * a + *tY * (1 - a); @@ -959,6 +962,8 @@ Image::alpha_blend (shared_ptr other, Position position) other->size(), other->data(), other->stride(), + nullptr, + nullptr }; auto byteswap = [](uint16_t* p) { @@ -1015,7 +1020,9 @@ Image::alpha_blend (shared_ptr other, Position position) auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); other_yuv_params.data = yuv->data(); other_yuv_params.stride = yuv->stride(); - alpha_blend_onto_yuv420p(target_params, other_yuv_params, other->data(), other->stride()); + other_yuv_params.alpha_data = other->data(); + other_yuv_params.alpha_stride = other->stride(); + alpha_blend_onto_yuv420p(target_params, other_yuv_params); break; } case AV_PIX_FMT_YUV420P10: @@ -1023,7 +1030,9 @@ Image::alpha_blend (shared_ptr other, Position position) auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); other_yuv_params.data = yuv->data(); other_yuv_params.stride = yuv->stride(); - alpha_blend_onto_yuv420p10(target_params, other_yuv_params, other->data(), other->stride()); + other_yuv_params.alpha_data = other->data(); + other_yuv_params.alpha_stride = other->stride(); + alpha_blend_onto_yuv420p10(target_params, other_yuv_params); break; } case AV_PIX_FMT_YUV422P9LE: @@ -1032,7 +1041,7 @@ Image::alpha_blend (shared_ptr other, Position position) auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); other_yuv_params.data = yuv->data(); other_yuv_params.stride = yuv->stride(); - alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params, other->data(), other->stride()); + alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params); break; } default: -- cgit v1.2.3 From cf7df384d7698c0d75342e02b7efdbacf8611398 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Jan 2024 11:38:39 +0100 Subject: Fix incorrect alpha step used for RGBA64 sources. --- src/lib/image.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 4042d5886..98c52c8e0 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -673,6 +673,7 @@ struct OtherYUVParams uint8_t* const* alpha_data; int const* alpha_stride; + int alpha_bpp; }; @@ -816,7 +817,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other uint8_t* oY = other.data[0] + (oy * other.stride[0]) + other.start_x; uint8_t* oU = other.data[1] + (hoy * other.stride[1]) + other.start_x / 2; uint8_t* oV = other.data[2] + (hoy * other.stride[2]) + other.start_x / 2; - uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { float const a = float(alpha[3]) / 255; *tY = *oY * a + *tY * (1 - a); @@ -832,7 +833,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other ++oU; ++oV; } - alpha += 4; + alpha += other.alpha_bpp; } } } @@ -853,7 +854,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& oth uint16_t* oY = reinterpret_cast(other.data[0] + (oy * other.stride[0])) + other.start_x; uint16_t* oU = reinterpret_cast(other.data[1] + (hoy * other.stride[1])) + other.start_x / 2; uint16_t* oV = reinterpret_cast(other.data[2] + (hoy * other.stride[2])) + other.start_x / 2; - uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { float const a = float(alpha[3]) / 255; *tY = *oY * a + *tY * (1 - a); @@ -869,7 +870,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& oth ++oU; ++oV; } - alpha += 4; + alpha += other.alpha_bpp; } } } @@ -888,7 +889,7 @@ alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const uint16_t* oY = reinterpret_cast(other.data[0] + (oy * other.stride[0])) + other.start_x; uint16_t* oU = reinterpret_cast(other.data[1] + (oy * other.stride[1])) + other.start_x / 2; uint16_t* oV = reinterpret_cast(other.data[2] + (oy * other.stride[2])) + other.start_x / 2; - uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * 4; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { float const a = float(alpha[3]) / 255; *tY = *oY * a + *tY * (1 - a); @@ -904,7 +905,7 @@ alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const ++oU; ++oV; } - alpha += 4; + alpha += other.alpha_bpp; } } } @@ -963,7 +964,8 @@ Image::alpha_blend (shared_ptr other, Position position) other->data(), other->stride(), nullptr, - nullptr + nullptr, + other->pixel_format() == AV_PIX_FMT_RGBA64BE ? 8 : 4 }; auto byteswap = [](uint16_t* p) { -- cgit v1.2.3 From 150ee308a8a802df6e65a957bb256e891d12835e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Jan 2024 12:16:55 +0100 Subject: Fix incorrect alpha channel scaling with RGBA64. --- src/lib/image.cc | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 98c52c8e0..366c1ae35 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -804,7 +804,7 @@ alpha_blend_onto_xyz12le(TargetParams const& target, OtherRGBParams const& other static void -alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other) +alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other, std::function get_alpha) { auto const ts = target.size; auto const os = other.size; @@ -819,7 +819,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other uint8_t* oV = other.data[2] + (hoy * other.stride[2]) + other.start_x / 2; uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { - float const a = float(alpha[3]) / 255; + float const a = get_alpha(alpha); *tY = *oY * a + *tY * (1 - a); *tU = *oU * a + *tU * (1 - a); *tV = *oV * a + *tV * (1 - a); @@ -841,7 +841,7 @@ alpha_blend_onto_yuv420p(TargetParams const& target, OtherYUVParams const& other static void -alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other) +alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& other, std::function get_alpha) { auto const ts = target.size; auto const os = other.size; @@ -856,7 +856,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& oth uint16_t* oV = reinterpret_cast(other.data[2] + (hoy * other.stride[2])) + other.start_x / 2; uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { - float const a = float(alpha[3]) / 255; + float const a = get_alpha(alpha); *tY = *oY * a + *tY * (1 - a); *tU = *oU * a + *tU * (1 - a); *tV = *oV * a + *tV * (1 - a); @@ -878,7 +878,7 @@ alpha_blend_onto_yuv420p10(TargetParams const& target, OtherYUVParams const& oth static void -alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other) +alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const& other, std::function get_alpha) { auto const ts = target.size; auto const os = other.size; @@ -891,7 +891,7 @@ alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const uint16_t* oV = reinterpret_cast(other.data[2] + (oy * other.stride[2])) + other.start_x / 2; uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { - float const a = float(alpha[3]) / 255; + float const a = get_alpha(alpha); *tY = *oY * a + *tY * (1 - a); *tU = *oU * a + *tU * (1 - a); *tV = *oV * a + *tV * (1 - a); @@ -976,6 +976,14 @@ Image::alpha_blend (shared_ptr other, Position position) return *p; }; + auto get_alpha_64be = [](uint8_t* p) { + return ((static_cast(p[6]) << 8) | p[7]) / 65535.0f; + }; + + auto get_alpha_byte = [](uint8_t* p) { + return p[3] / 255.0f; + }; + switch (_pixel_format) { case AV_PIX_FMT_RGB24: target_params.bpp = 3; @@ -1024,7 +1032,11 @@ Image::alpha_blend (shared_ptr other, Position position) other_yuv_params.stride = yuv->stride(); other_yuv_params.alpha_data = other->data(); other_yuv_params.alpha_stride = other->stride(); - alpha_blend_onto_yuv420p(target_params, other_yuv_params); + if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { + alpha_blend_onto_yuv420p(target_params, other_yuv_params, get_alpha_64be); + } else { + alpha_blend_onto_yuv420p(target_params, other_yuv_params, get_alpha_byte); + } break; } case AV_PIX_FMT_YUV420P10: @@ -1034,7 +1046,11 @@ Image::alpha_blend (shared_ptr other, Position position) other_yuv_params.stride = yuv->stride(); other_yuv_params.alpha_data = other->data(); other_yuv_params.alpha_stride = other->stride(); - alpha_blend_onto_yuv420p10(target_params, other_yuv_params); + if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { + alpha_blend_onto_yuv420p10(target_params, other_yuv_params, get_alpha_64be); + } else { + alpha_blend_onto_yuv420p10(target_params, other_yuv_params, get_alpha_byte); + } break; } case AV_PIX_FMT_YUV422P9LE: @@ -1043,7 +1059,13 @@ Image::alpha_blend (shared_ptr other, Position position) auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); other_yuv_params.data = yuv->data(); other_yuv_params.stride = yuv->stride(); - alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params); + other_yuv_params.alpha_data = other->data(); + other_yuv_params.alpha_stride = other->stride(); + if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { + alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params, get_alpha_64be); + } else { + alpha_blend_onto_yuv422p9or10le(target_params, other_yuv_params, get_alpha_byte); + } break; } default: -- cgit v1.2.3 From 9d1d1cea1cdf17b4cc2208800ca22288f979d3ec Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Jan 2024 12:43:08 +0100 Subject: Support alpha blend onto YUV444P9LE and YUV444P10LE (68 and 70). --- src/lib/image.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ test/image_test.cc | 4 ++++ 2 files changed, 50 insertions(+) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 366c1ae35..801b39b0f 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -911,6 +911,37 @@ alpha_blend_onto_yuv422p9or10le(TargetParams const& target, OtherYUVParams const } +static +void +alpha_blend_onto_yuv444p9or10le(TargetParams const& target, OtherYUVParams const& other, std::function get_alpha) +{ + auto const ts = target.size; + auto const os = other.size; + for (int ty = target.start_y, oy = other.start_y; ty < ts.height && oy < os.height; ++ty, ++oy) { + uint16_t* tY = reinterpret_cast(target.data[0] + (ty * target.stride[0])) + target.start_x; + uint16_t* tU = reinterpret_cast(target.data[1] + (ty * target.stride[1])) + target.start_x; + uint16_t* tV = reinterpret_cast(target.data[2] + (ty * target.stride[2])) + target.start_x; + uint16_t* oY = reinterpret_cast(other.data[0] + (oy * other.stride[0])) + other.start_x; + uint16_t* oU = reinterpret_cast(other.data[1] + (oy * other.stride[1])) + other.start_x; + uint16_t* oV = reinterpret_cast(other.data[2] + (oy * other.stride[2])) + other.start_x; + uint8_t* alpha = other.alpha_data[0] + (oy * other.alpha_stride[0]) + other.start_x * other.alpha_bpp; + for (int tx = target.start_x, ox = other.start_x; tx < ts.width && ox < os.width; ++tx, ++ox) { + float const a = get_alpha(alpha); + *tY = *oY * a + *tY * (1 - a); + *tU = *oU * a + *tU * (1 - a); + *tV = *oV * a + *tV * (1 - a); + ++tY; + ++oY; + ++tU; + ++tV; + ++oU; + ++oV; + alpha += other.alpha_bpp; + } + } +} + + void Image::alpha_blend (shared_ptr other, Position position) { @@ -1068,6 +1099,21 @@ Image::alpha_blend (shared_ptr other, Position position) } break; } + case AV_PIX_FMT_YUV444P9LE: + case AV_PIX_FMT_YUV444P10LE: + { + auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, Alignment::COMPACT, false); + other_yuv_params.data = yuv->data(); + other_yuv_params.stride = yuv->stride(); + other_yuv_params.alpha_data = other->data(); + other_yuv_params.alpha_stride = other->stride(); + if (other->pixel_format() == AV_PIX_FMT_RGBA64BE) { + alpha_blend_onto_yuv444p9or10le(target_params, other_yuv_params, get_alpha_64be); + } else { + alpha_blend_onto_yuv444p9or10le(target_params, other_yuv_params, get_alpha_byte); + } + break; + } default: throw PixelFormatError ("alpha_blend()", _pixel_format); } diff --git a/test/image_test.cc b/test/image_test.cc index 190e550ab..cad30813c 100644 --- a/test/image_test.cc +++ b/test/image_test.cc @@ -244,6 +244,8 @@ BOOST_AUTO_TEST_CASE (alpha_blend_test) alpha_blend_test_bgra_onto(AV_PIX_FMT_YUV420P10, "yuv420p10"); alpha_blend_test_bgra_onto(AV_PIX_FMT_YUV422P9LE, "yuv422p9le"); alpha_blend_test_bgra_onto(AV_PIX_FMT_YUV422P10LE, "yuv422p10le"); + alpha_blend_test_bgra_onto(AV_PIX_FMT_YUV444P9LE, "yuv444p9le"); + alpha_blend_test_bgra_onto(AV_PIX_FMT_YUV444P10LE, "yuv444p10le"); alpha_blend_test_rgba64be_onto(AV_PIX_FMT_RGB24, "rgb24"); alpha_blend_test_rgba64be_onto(AV_PIX_FMT_BGRA, "bgra"); @@ -253,6 +255,8 @@ BOOST_AUTO_TEST_CASE (alpha_blend_test) alpha_blend_test_rgba64be_onto(AV_PIX_FMT_YUV420P10, "yuv420p10"); alpha_blend_test_rgba64be_onto(AV_PIX_FMT_YUV422P9LE, "yuv422p9le"); alpha_blend_test_rgba64be_onto(AV_PIX_FMT_YUV422P10LE, "yuv422p10le"); + alpha_blend_test_rgba64be_onto(AV_PIX_FMT_YUV444P9LE, "yuv444p9le"); + alpha_blend_test_rgba64be_onto(AV_PIX_FMT_YUV444P10LE, "yuv444p10le"); } -- cgit v1.2.3 From 54ca161fd074a7ba17d9aed8479da189374eb64e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 1 Feb 2024 13:28:38 +0100 Subject: Add some asserts; sws_getContext() will fail if the image width or height are 0. --- src/lib/image.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 801b39b0f..4c60fe888 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -339,6 +339,10 @@ Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_fo the input image alignment is not PADDED. */ DCPOMATIC_ASSERT (alignment() == Alignment::PADDED); + DCPOMATIC_ASSERT(size().width > 0); + DCPOMATIC_ASSERT(size().height > 0); + DCPOMATIC_ASSERT(out_size.width > 0); + DCPOMATIC_ASSERT(out_size.height > 0); auto scaled = make_shared(out_format, out_size, out_alignment); auto scale_context = sws_getContext ( -- cgit v1.2.3 From 092c23dde5ad89e8dc8d31b83154b5ac58f5a7f2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 1 Feb 2024 13:28:49 +0100 Subject: Add an assert to check that sws_getContext() succeeded. --- src/lib/image.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 4c60fe888..2167918f8 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -351,6 +351,8 @@ Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_fo (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0 ); + DCPOMATIC_ASSERT(scale_context); + DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT); EnumIndexedVector lut; lut[dcp::YUVToRGB::REC601] = SWS_CS_ITU601; -- cgit v1.2.3 From 79ee0e5e79d8fb4a405d8b29827347d0243a17fe Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 1 Feb 2024 13:29:53 +0100 Subject: Don't emit subtitle images that have a zero dimension (#2743). They cause problems later when trying to blend them into the image. --- run/tests | 2 +- src/lib/player.cc | 7 +++++-- test/burnt_subtitle_test.cc | 22 ++++++++++++++++++++++ test/data | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/run/tests b/run/tests index 12d59346d..4315e227f 100755 --- a/run/tests +++ b/run/tests @@ -3,7 +3,7 @@ # e.g. --run_tests=foo set -e -PRIVATE_GIT="59b62615a48a1f3a70e9c028b92dfba75c1719ba" +PRIVATE_GIT="f4b0c41b263a17cf33edae7565f16bd21eb80b65" if [ "$1" == "--check" ]; then shift 1 diff --git a/src/lib/player.cc b/src/lib/player.cc index ef7ecde5a..79b48ea71 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -921,7 +921,7 @@ Player::open_subtitles_for_frame (DCPTime time) const /* Bitmap subtitles */ for (auto i: j.bitmap) { - if (!i.image) { + if (!i.image || i.image->size().width == 0 || i.image->size().height == 0) { continue; } @@ -942,7 +942,10 @@ Player::open_subtitles_for_frame (DCPTime time) const /* String subtitles (rendered to an image) */ if (!j.string.empty()) { auto s = render_text(j.string, _video_container_size, time, vfr); - copy (s.begin(), s.end(), back_inserter (captions)); + copy_if(s.begin(), s.end(), back_inserter(captions), [](PositionImage const& image) { + return image.image->size().width && image.image->size().height; + }); + } } diff --git a/test/burnt_subtitle_test.cc b/test/burnt_subtitle_test.cc index 9c6863a1d..8d7dcd143 100644 --- a/test/burnt_subtitle_test.cc +++ b/test/burnt_subtitle_test.cc @@ -30,6 +30,7 @@ #include "lib/dcp_content.h" #include "lib/dcp_content_type.h" #include "lib/film.h" +#include "lib/ffmpeg_encoder.h" #include "lib/log_entry.h" #include "lib/ratio.h" #include "lib/text_content.h" @@ -184,3 +185,24 @@ BOOST_AUTO_TEST_CASE(burnt_subtitle_test_position) /* Should have a baseline 864 pixels from the top ((1 - 0.2) * 1080) */ check("bottom"); } + + +/* Bug #2743 */ +BOOST_AUTO_TEST_CASE(burn_empty_subtitle_test) +{ + Cleanup cl; + + auto content = content_factory("test/data/empty_sub.xml")[0]; + auto film = new_test_film2("burnt_empty_subtitle_test", { content }); + content->text[0]->set_use(true); + + auto job = make_shared(film, TranscodeJob::ChangedBehaviour::IGNORE); + auto file = boost::filesystem::path("build") / "test" / "burnt_empty_subtitle_test.mov"; + cl.add(file); + FFmpegEncoder encoder(film, job, file, ExportFormat::PRORES_4444, false, false, false, 23); + encoder.go(); + + cl.run(); +} + + diff --git a/test/data b/test/data index a81d5737e..704f76433 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit a81d5737e54105f95d3d0cbf602dd355b8814244 +Subproject commit 704f7643393caa29d77ddba138bff3642b273c46 -- cgit v1.2.3 From c9e807a398ffa4c6ba38a26e2721250bdbef10d7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 3 Feb 2024 10:19:22 +0100 Subject: Supporters update. --- src/wx/supporters.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/wx/supporters.cc b/src/wx/supporters.cc index e4e5cb07a..beb4d967a 100644 --- a/src/wx/supporters.cc +++ b/src/wx/supporters.cc @@ -160,6 +160,7 @@ supported_by.Add (wxT ("Marco Valerio Caminiti")); supported_by.Add (wxT ("Lachlan Campbell")); supported_by.Add (wxT ("Edward Campos")); supported_by.Add (wxT ("Luis Canau")); +supported_by.Add (wxT ("Francesco Cappellini")); supported_by.Add (wxT ("Paul Carey")); supported_by.Add (wxT ("P. G. Carmona")); supported_by.Add (wxT ("Kevin Carney")); @@ -203,7 +204,7 @@ supported_by.Add (wxT ("Grand Illusion Cinema")); supported_by.Add (wxT ("Flathead Lake International Cinemafest")); supported_by.Add (wxT ("Leduc Cinemas")); supported_by.Add (wxT ("Cinematic")); -supported_by.Add (wxT ("Zach & Zach Cinérgie")); +supported_by.Add (wxT ("Zach && Zach Cinérgie")); supported_by.Add (wxT ("Cinestudio")); supported_by.Add (wxT ("Cinema Clarici")); supported_by.Add (wxT ("Berendina Clason")); @@ -231,7 +232,7 @@ supported_by.Add (wxT ("Tom Cowan")); supported_by.Add (wxT ("Jill Cox")); supported_by.Add (wxT ("Stefano Cravero")); supported_by.Add (wxT ("Phillip Crawford")); -supported_by.Add (wxT ("Root & Rust Creative")); +supported_by.Add (wxT ("Root && Rust Creative")); supported_by.Add (wxT ("Caribbean Creativity")); supported_by.Add (wxT ("Ailis Cross-Gorman")); supported_by.Add (wxT ("Rodrigo Hernández Cruz")); @@ -362,6 +363,7 @@ supported_by.Add (wxT ("KulturKino Feuchtwangen")); supported_by.Add (wxT ("Lorenzo Fiale")); supported_by.Add (wxT ("Dean Fick")); supported_by.Add (wxT ("Marc Fiebig")); +supported_by.Add (wxT ("Moshel Film")); supported_by.Add (wxT ("Juli Film")); supported_by.Add (wxT ("Pató Film")); supported_by.Add (wxT ("Hoppe Film")); @@ -370,7 +372,7 @@ supported_by.Add (wxT ("Hamann Film")); supported_by.Add (wxT ("Traverse City Film Festival")); supported_by.Add (wxT ("Z-fest Film Project")); supported_by.Add (wxT ("DIAMETRALE Filmfestival")); -supported_by.Add (wxT ("Lichtwerk & Kamera Filmkunst")); +supported_by.Add (wxT ("Lichtwerk && Kamera Filmkunst")); supported_by.Add (wxT ("Casablanca Filmkunsttheater")); supported_by.Add (wxT ("Redscope Filmproducties")); supported_by.Add (wxT ("Lukas Thiele Filmproduktion")); @@ -732,14 +734,14 @@ supported_by.Add (wxT ("Juan Marin Lorenzo")); supported_by.Add (wxT ("Tim Lorge")); supported_by.Add (wxT ("Thomas Lorin")); supported_by.Add (wxT ("Leonard Louder")); -supported_by.Add (wxT ("Auguste & Louise")); +supported_by.Add (wxT ("Auguste && Louise")); supported_by.Add (wxT ("Cubic Films Pty Ltd")); supported_by.Add (wxT ("First And Only Ltd")); supported_by.Add (wxT ("Quiet Heart Film PTY LTD")); supported_by.Add (wxT ("The Digital Picture House Ltd")); supported_by.Add (wxT ("Futurilla Ltd")); supported_by.Add (wxT ("Sector Zero Ltd")); -supported_by.Add (wxT ("Lewis & Coleman Consulting Services Pty Ltd")); +supported_by.Add (wxT ("Lewis && Coleman Consulting Services Pty Ltd")); supported_by.Add (wxT ("Keen i Media Ltd")); supported_by.Add (wxT ("Ted Lubin")); supported_by.Add (wxT ("Michael Luce")); @@ -770,7 +772,7 @@ supported_by.Add (wxT ("MantaRay.Media")); supported_by.Add (wxT ("Maxim Mantel")); supported_by.Add (wxT ("Nick Manting-Brewer")); supported_by.Add (wxT ("Marc Levy from The Marcs")); -supported_by.Add (wxT ("Job, Joris & Marieke")); +supported_by.Add (wxT ("Job, Joris && Marieke")); supported_by.Add (wxT ("Stoyan Marinov")); supported_by.Add (wxT ("Ruben Marques")); supported_by.Add (wxT ("Francisco M Ortega Marquez")); @@ -982,6 +984,7 @@ supported_by.Add (wxT ("Kino ist Programm")); supported_by.Add (wxT ("Sem Rumo — Projetos Audiovisuais")); supported_by.Add (wxT ("ProsetschioPictures")); supported_by.Add (wxT ("Ivan Pullman")); +supported_by.Add (wxT ("Milos Pusic")); supported_by.Add (wxT ("John Quackenbush")); supported_by.Add (wxT ("Festival De Cinéma De La Ville De Québec")); supported_by.Add (wxT ("Arts Quest")); @@ -1087,7 +1090,7 @@ supported_by.Add (wxT ("Brendan Shoebridge")); supported_by.Add (wxT ("Tiffany Sia")); supported_by.Add (wxT ("Konstantin V. Sichart")); supported_by.Add (wxT ("Atli Sigurjonsson")); -supported_by.Add (wxT ("Andre & Shannon Silva")); +supported_by.Add (wxT ("Andre && Shannon Silva")); supported_by.Add (wxT ("Daniele Silvestri")); supported_by.Add (wxT ("Benjamin Simmons")); supported_by.Add (wxT ("Peter Six")); @@ -1266,6 +1269,7 @@ supported_by.Add (wxT ("Mike Wilde")); supported_by.Add (wxT ("Andrew Wilhelm")); supported_by.Add (wxT ("Edgar Wilkening")); supported_by.Add (wxT ("Maya Willcocks")); +supported_by.Add (wxT ("Steven Willemin")); supported_by.Add (wxT ("Roland Wirtz")); supported_by.Add (wxT ("Sean Wirz")); supported_by.Add (wxT ("Volker Wischnowski")); -- cgit v1.2.3