X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fproducer%2Fframe%2Fimage_transform.cpp;h=6c3d6eb90a52372752375417535df73e7cb20860;hb=ba52ab6a5ed8312b906d2e28c12984281cfcff75;hp=c23a57b9412e0a007e72462c12d6c93f4cb583a7;hpb=7bf35a58a785d5417667faae97ee75a802d96d44;p=casparcg diff --git a/core/producer/frame/image_transform.cpp b/core/producer/frame/image_transform.cpp index c23a57b94..6c3d6eb90 100644 --- a/core/producer/frame/image_transform.cpp +++ b/core/producer/frame/image_transform.cpp @@ -17,6 +17,7 @@ * along with CasparCG. If not, see . * */ +// TODO: Move layer specific stuff out of frame related classes. #include "../../stdafx.h" #include "image_transform.h" @@ -30,10 +31,11 @@ namespace caspar { namespace core { image_transform::image_transform() : opacity_(1.0) , gain_(1.0) - , mode_(video_mode::invalid) + , brightness_(1.0) + , contrast_(1.0) + , saturation_(1.0) , is_key_(false) - , deinterlace_(false) - , blend_mode_(image_transform::normal) + , blend_mode_(image_transform::blend_mode::normal) { std::fill(fill_translation_.begin(), fill_translation_.end(), 0.0); std::fill(fill_scale_.begin(), fill_scale_.end(), 1.0); @@ -61,6 +63,47 @@ double image_transform::get_gain() const return gain_; } +void image_transform::set_brightness(double value) +{ + brightness_ = std::max(0.0, value); +} + +double image_transform::get_brightness() const +{ + return brightness_; +} + +void image_transform::set_contrast(double value) +{ + contrast_ = std::max(0.0, value); +} + +double image_transform::get_contrast() const +{ + return contrast_; +} + +void image_transform::set_saturation(double value) +{ + saturation_ = std::max(0.0, value); +} + +double image_transform::get_saturation() const +{ + return saturation_; +} + +void image_transform::set_levels(const image_transform::levels& value) +{ + levels_ = value; +} + +image_transform::levels image_transform::get_levels() const +{ + return levels_; +} + + void image_transform::set_fill_translation(double x, double y) { fill_translation_[0] = x; @@ -105,46 +148,33 @@ std::array image_transform::get_clip_scale() const return clip_scale_; } -void image_transform::set_mode(video_mode::type mode) -{ - mode_ = mode; -} - -video_mode::type image_transform::get_mode() const -{ - return mode_; -} - -void image_transform::set_deinterlace(bool value) -{ - deinterlace_ = value; -} - -bool image_transform::get_deinterlace() const -{ - return deinterlace_; -} - -void image_transform::set_blend_mode(image_transform::blend_mode value) +void image_transform::set_blend_mode(image_transform::blend_mode::type value) { blend_mode_ = value; } -image_transform::blend_mode image_transform::get_blend_mode() const +image_transform::blend_mode::type image_transform::get_blend_mode() const { return blend_mode_; } image_transform& image_transform::operator*=(const image_transform &other) { - opacity_ *= other.opacity_; - - if(other.mode_ != video_mode::invalid) - mode_ = other.mode_; - + opacity_ *= other.opacity_; blend_mode_ = std::max(blend_mode_, other.blend_mode_); gain_ *= other.gain_; - deinterlace_ |= other.deinterlace_; + brightness_ *= other.brightness_; + contrast_ *= other.contrast_; + saturation_ *= other.saturation_; + + levels_.min_input = std::max(levels_.min_input, other.levels_.min_input); + levels_.max_input = std::min(levels_.max_input, other.levels_.max_input); + + levels_.min_output = std::max(levels_.min_output, other.levels_.min_output); + levels_.max_output = std::min(levels_.max_output, other.levels_.max_output); + + levels_.gamma *= other.levels_.gamma; + is_key_ |= other.is_key_; fill_translation_[0] += other.fill_translation_[0]*fill_scale_[0]; fill_translation_[1] += other.fill_translation_[1]*fill_scale_[1]; @@ -171,86 +201,113 @@ image_transform tween(double time, const image_transform& source, const image_tr { return tweener(time, source, dest-source, duration); }; - - CASPAR_ASSERT(source.get_mode() == dest.get_mode() || source.get_mode() == video_mode::invalid || dest.get_mode() == video_mode::invalid); - + image_transform result; - result.set_mode (dest.get_mode() != video_mode::invalid ? dest.get_mode() : source.get_mode()); result.set_blend_mode (std::max(source.get_blend_mode(), dest.get_blend_mode())); result.set_is_key (source.get_is_key() | dest.get_is_key()); - result.set_deinterlace (source.get_deinterlace() | dest.get_deinterlace()); result.set_gain (do_tween(time, source.get_gain(), dest.get_gain(), duration, tweener)); + result.set_brightness (do_tween(time, source.get_brightness(), dest.get_brightness(), duration, tweener)); + result.set_contrast (do_tween(time, source.get_contrast(), dest.get_contrast(), duration, tweener)); + result.set_saturation (do_tween(time, source.get_saturation(), dest.get_saturation(), duration, tweener)); result.set_opacity (do_tween(time, source.get_opacity(), dest.get_opacity(), duration, tweener)); result.set_fill_translation (do_tween(time, source.get_fill_translation()[0], dest.get_fill_translation()[0], duration, tweener), do_tween(time, source.get_fill_translation()[1], dest.get_fill_translation()[1], duration, tweener)); result.set_fill_scale (do_tween(time, source.get_fill_scale()[0], dest.get_fill_scale()[0], duration, tweener), do_tween(time, source.get_fill_scale()[1], dest.get_fill_scale()[1], duration, tweener)); result.set_clip_translation (do_tween(time, source.get_clip_translation()[0], dest.get_clip_translation()[0], duration, tweener), do_tween(time, source.get_clip_translation()[1], dest.get_clip_translation()[1], duration, tweener)); result.set_clip_scale (do_tween(time, source.get_clip_scale()[0], dest.get_clip_scale()[0], duration, tweener), do_tween(time, source.get_clip_scale()[1], dest.get_clip_scale()[1], duration, tweener)); + auto s_levels = source.get_levels(); + auto d_levels = dest.get_levels(); + + d_levels.max_input = do_tween(time, s_levels.max_input, d_levels.max_input, duration, tweener); + d_levels.min_input = do_tween(time, s_levels.min_input, d_levels.min_input, duration, tweener); + + d_levels.max_output = do_tween(time, s_levels.max_output, d_levels.max_output, duration, tweener); + d_levels.min_output = do_tween(time, s_levels.min_output, d_levels.min_output, duration, tweener); + + d_levels.gamma = do_tween(time, s_levels.gamma, d_levels.gamma, duration, tweener); + + result.set_levels(d_levels); + return result; } -image_transform::blend_mode get_blend_mode(const std::wstring& str) +image_transform::blend_mode::type get_blend_mode(const std::wstring& str) { if(boost::iequals(str, L"normal")) - return image_transform::normal; + return image_transform::blend_mode::normal; else if(boost::iequals(str, L"lighten")) - return image_transform::lighten; + return image_transform::blend_mode::lighten; else if(boost::iequals(str, L"darken")) - return image_transform::darken; + return image_transform::blend_mode::darken; else if(boost::iequals(str, L"multiply")) - return image_transform::multiply; + return image_transform::blend_mode::multiply; else if(boost::iequals(str, L"average")) - return image_transform::average; + return image_transform::blend_mode::average; else if(boost::iequals(str, L"add")) - return image_transform::add; + return image_transform::blend_mode::add; else if(boost::iequals(str, L"subtract")) - return image_transform::subtract; + return image_transform::blend_mode::subtract; else if(boost::iequals(str, L"difference")) - return image_transform::difference; + return image_transform::blend_mode::difference; else if(boost::iequals(str, L"negation")) - return image_transform::negation; + return image_transform::blend_mode::negation; else if(boost::iequals(str, L"exclusion")) - return image_transform::exclusion; + return image_transform::blend_mode::exclusion; else if(boost::iequals(str, L"screen")) - return image_transform::screen; + return image_transform::blend_mode::screen; else if(boost::iequals(str, L"overlay")) - return image_transform::overlay; + return image_transform::blend_mode::overlay; else if(boost::iequals(str, L"soft_light")) - return image_transform::soft_light; + return image_transform::blend_mode::soft_light; else if(boost::iequals(str, L"hard_light")) - return image_transform::hard_light; + return image_transform::blend_mode::hard_light; else if(boost::iequals(str, L"color_dodge")) - return image_transform::color_dodge; + return image_transform::blend_mode::color_dodge; else if(boost::iequals(str, L"color_burn")) - return image_transform::color_burn; + return image_transform::blend_mode::color_burn; else if(boost::iequals(str, L"linear_dodge")) - return image_transform::linear_dodge; + return image_transform::blend_mode::linear_dodge; else if(boost::iequals(str, L"linear_burn")) - return image_transform::linear_burn; + return image_transform::blend_mode::linear_burn; else if(boost::iequals(str, L"linear_light")) - return image_transform::linear_light; + return image_transform::blend_mode::linear_light; else if(boost::iequals(str, L"vivid_light")) - return image_transform::vivid_light; + return image_transform::blend_mode::vivid_light; else if(boost::iequals(str, L"pin_light")) - return image_transform::pin_light; + return image_transform::blend_mode::pin_light; else if(boost::iequals(str, L"hard_mix")) - return image_transform::hard_mix; + return image_transform::blend_mode::hard_mix; else if(boost::iequals(str, L"reflect")) - return image_transform::reflect; + return image_transform::blend_mode::reflect; else if(boost::iequals(str, L"glow")) - return image_transform::glow; + return image_transform::blend_mode::glow; else if(boost::iequals(str, L"phoenix")) - return image_transform::phoenix; - else if(boost::iequals(str, L"hue")) - return image_transform::hue; + return image_transform::blend_mode::phoenix; + else if(boost::iequals(str, L"contrast")) + return image_transform::blend_mode::contrast; else if(boost::iequals(str, L"saturation")) - return image_transform::saturation; + return image_transform::blend_mode::saturation; else if(boost::iequals(str, L"color")) - return image_transform::color; + return image_transform::blend_mode::color; else if(boost::iequals(str, L"luminosity")) - return image_transform::luminosity; + return image_transform::blend_mode::luminosity; - return image_transform::normal; + return image_transform::blend_mode::normal; +} + +bool operator<(const image_transform& lhs, const image_transform& rhs) +{ + return memcmp(&lhs, &rhs, sizeof(image_transform)) < 0; +} + +bool operator==(const image_transform& lhs, const image_transform& rhs) +{ + return memcmp(&lhs, &rhs, sizeof(image_transform)) == 0; +} + +bool operator!=(const image_transform& lhs, const image_transform& rhs) +{ + return !(lhs == rhs); } }} \ No newline at end of file