]> git.sesse.net Git - casparcg/blobdiff - core/producer/frame/image_transform.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / core / producer / frame / image_transform.cpp
index d916ca101d598501b484c45f1d2c6cf4054ff8bb..9d78faa7b0f6c54e1f91d06a437b82a94277a398 100644 (file)
@@ -17,6 +17,7 @@
 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
 *\r
 */\r
+// TODO: Move layer specific stuff out of frame related classes.\r
 #include "../../stdafx.h"\r
 \r
 #include "image_transform.h"\r
@@ -27,11 +28,11 @@ namespace caspar { namespace core {
                \r
 image_transform::image_transform() \r
        : opacity_(1.0)\r
-       , gain_(1.0)\r
-       , mode_(video_mode::invalid)\r
+       , brightness_(1.0)\r
+       , contrast_(1.0)\r
+       , saturation_(1.0)\r
        , is_key_(false)\r
-       , deinterlace_(false)\r
-       , blend_mode_(image_transform::normal)\r
+       , field_mode_(field_mode::progressive)\r
 {\r
        std::fill(fill_translation_.begin(), fill_translation_.end(), 0.0);\r
        std::fill(fill_scale_.begin(), fill_scale_.end(), 1.0);\r
@@ -49,16 +50,47 @@ double image_transform::get_opacity() const
        return opacity_;\r
 }\r
 \r
-void image_transform::set_gain(double value)\r
+void image_transform::set_brightness(double value)\r
 {\r
-       gain_ = std::max(0.0, value);\r
+       brightness_ = std::max(0.0, value);\r
 }\r
 \r
-double image_transform::get_gain() const\r
+double image_transform::get_brightness() const\r
 {\r
-       return gain_;\r
+       return brightness_;\r
 }\r
 \r
+void image_transform::set_contrast(double value)\r
+{\r
+       contrast_ = std::max(0.0, value);\r
+}\r
+\r
+double image_transform::get_contrast() const\r
+{\r
+       return contrast_;\r
+}\r
+\r
+void image_transform::set_saturation(double value)\r
+{\r
+       saturation_ = std::max(0.0, value);\r
+}\r
+\r
+double image_transform::get_saturation() const\r
+{\r
+       return saturation_;\r
+}\r
+\r
+void image_transform::set_levels(const image_transform::levels& value)\r
+{\r
+       levels_ = value;\r
+}\r
+\r
+image_transform::levels image_transform::get_levels() const\r
+{\r
+       return levels_;\r
+}\r
+\r
+\r
 void image_transform::set_fill_translation(double x, double y)\r
 {\r
        fill_translation_[0] = x;\r
@@ -103,46 +135,32 @@ std::array<double, 2> image_transform::get_clip_scale() const
        return clip_scale_;\r
 }\r
 \r
-void image_transform::set_mode(video_mode::type mode)\r
-{\r
-       mode_ = mode;\r
-}\r
-\r
-video_mode::type image_transform::get_mode() const\r
-{\r
-       return mode_;\r
-}\r
-\r
-void image_transform::set_deinterlace(bool value)\r
+void image_transform::set_field_mode(field_mode::type field_mode)\r
 {\r
-       deinterlace_ = value;\r
+       field_mode_ = field_mode;\r
 }\r
 \r
-bool image_transform::get_deinterlace() const\r
+field_mode::type image_transform::get_field_mode() const\r
 {\r
-       return deinterlace_;\r
-}\r
-\r
-void image_transform::set_blend_mode(image_transform::blend_mode value)\r
-{\r
-       blend_mode_ = value;\r
-}\r
-\r
-image_transform::blend_mode image_transform::get_blend_mode() const\r
-{\r
-       return blend_mode_;\r
+       return field_mode_;\r
 }\r
 \r
 image_transform& image_transform::operator*=(const image_transform &other)\r
 {\r
-       opacity_                                *= other.opacity_;\r
+       opacity_                                *= other.opacity_;      \r
+       brightness_                             *= other.brightness_;\r
+       contrast_                               *= other.contrast_;\r
+       saturation_                             *= other.saturation_;\r
+\r
+       levels_.min_input               = std::max(levels_.min_input, other.levels_.min_input);\r
+       levels_.max_input               = std::min(levels_.max_input, other.levels_.max_input);\r
        \r
-       if(other.mode_ != video_mode::invalid)\r
-               mode_ = other.mode_;\r
+       levels_.min_output              = std::max(levels_.min_output, other.levels_.min_output);\r
+       levels_.max_output              = std::min(levels_.max_output, other.levels_.max_output);\r
 \r
-       blend_mode_                              = other.blend_mode_;\r
-       gain_                                   *= other.gain_;\r
-       deinterlace_                    |= other.deinterlace_;\r
+       levels_.gamma                   *= other.levels_.gamma;\r
+\r
+       field_mode_                             = static_cast<field_mode::type>(field_mode_ & other.field_mode_);\r
        is_key_                                 |= other.is_key_;\r
        fill_translation_[0]    += other.fill_translation_[0]*fill_scale_[0];\r
        fill_translation_[1]    += other.fill_translation_[1]*fill_scale_[1];\r
@@ -169,22 +187,48 @@ image_transform tween(double time, const image_transform& source, const image_tr
        {\r
                return tweener(time, source, dest-source, duration);\r
        };\r
-\r
-       CASPAR_ASSERT(source.get_mode() == dest.get_mode() || source.get_mode() == video_mode::invalid || dest.get_mode() == video_mode::invalid);\r
-\r
+       \r
        image_transform result; \r
-       result.set_mode                         (dest.get_mode() != video_mode::invalid ? dest.get_mode() : source.get_mode());\r
-       result.set_blend_mode           (dest.get_blend_mode());\r
        result.set_is_key                       (source.get_is_key() | dest.get_is_key());\r
-       result.set_deinterlace          (source.get_deinterlace() | dest.get_deinterlace());\r
-       result.set_gain                         (do_tween(time, source.get_gain(), dest.get_gain(), duration, tweener));\r
+       result.set_field_mode           (static_cast<field_mode::type>(source.get_field_mode() & dest.get_field_mode()));\r
+       result.set_brightness           (do_tween(time, source.get_brightness(), dest.get_brightness(), duration, tweener));\r
+       result.set_contrast                     (do_tween(time, source.get_contrast(), dest.get_contrast(), duration, tweener));\r
+       result.set_saturation           (do_tween(time, source.get_saturation(), dest.get_saturation(), duration, tweener));\r
        result.set_opacity                      (do_tween(time, source.get_opacity(), dest.get_opacity(), duration, tweener));\r
        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));\r
        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));\r
        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));\r
        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));\r
        \r
+       auto s_levels = source.get_levels();\r
+       auto d_levels = dest.get_levels();\r
+\r
+       d_levels.max_input = do_tween(time, s_levels.max_input, d_levels.max_input, duration, tweener);\r
+       d_levels.min_input = do_tween(time, s_levels.min_input, d_levels.min_input, duration, tweener);\r
+       \r
+       d_levels.max_output = do_tween(time, s_levels.max_output, d_levels.max_output, duration, tweener);\r
+       d_levels.min_output = do_tween(time, s_levels.min_output, d_levels.min_output, duration, tweener);\r
+\r
+       d_levels.gamma = do_tween(time, s_levels.gamma, d_levels.gamma, duration, tweener);\r
+\r
+       result.set_levels(d_levels);\r
+\r
        return result;\r
 }\r
 \r
+bool operator<(const image_transform& lhs, const image_transform& rhs)\r
+{\r
+       return memcmp(&lhs, &rhs, sizeof(image_transform)) < 0;\r
+}\r
+\r
+bool operator==(const image_transform& lhs, const image_transform& rhs)\r
+{\r
+       return memcmp(&lhs, &rhs, sizeof(image_transform)) == 0;\r
+}\r
+\r
+bool operator!=(const image_transform& lhs, const image_transform& rhs)\r
+{\r
+       return !(lhs == rhs);\r
+}\r
+\r
 }}
\ No newline at end of file