]> git.sesse.net Git - casparcg/blobdiff - core/frame/frame_transform.cpp
set svn:eol-style native on .h and .cpp files
[casparcg] / core / frame / frame_transform.cpp
index 5ebac4740a878dd1c4c5134a746c53696f831f82..f9c14f3aa3f1fa288d273015d61a7a9492098b07 100644 (file)
-/*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Robert Nagy, ronag89@gmail.com\r
-*/\r
-\r
-#include "../stdafx.h"\r
-\r
-#include "frame_transform.h"\r
-\r
-#include <boost/range/algorithm/equal.hpp>\r
-#include <boost/range/algorithm/fill.hpp>\r
-\r
-namespace caspar { namespace core {\r
-               \r
-// image_transform\r
-\r
-image_transform::image_transform() \r
-       : opacity(1.0)\r
-       , brightness(1.0)\r
-       , contrast(1.0)\r
-       , saturation(1.0)\r
-       , field_mode(field_mode::progressive)\r
-       , is_key(false)\r
-       , is_mix(false)\r
-       , is_still(false)\r
-{\r
-       boost::range::fill(fill_translation, 0.0);\r
-       boost::range::fill(fill_scale, 1.0);\r
-       boost::range::fill(clip_translation, 0.0);\r
-       boost::range::fill(clip_scale, 1.0);\r
-}\r
-\r
-image_transform& image_transform::operator*=(const image_transform &other)\r
-{\r
-       opacity                                 *= other.opacity;       \r
-       brightness                              *= other.brightness;\r
-       contrast                                *= other.contrast;\r
-       saturation                              *= other.saturation;\r
-       fill_translation[0]             += other.fill_translation[0]*fill_scale[0];\r
-       fill_translation[1]             += other.fill_translation[1]*fill_scale[1];\r
-       fill_scale[0]                   *= other.fill_scale[0];\r
-       fill_scale[1]                   *= other.fill_scale[1];\r
-       clip_translation[0]             += other.clip_translation[0]*clip_scale[0];\r
-       clip_translation[1]             += other.clip_translation[1]*clip_scale[1];\r
-       clip_scale[0]                   *= other.clip_scale[0];\r
-       clip_scale[1]                   *= other.clip_scale[1];\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
-       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
-       levels.gamma                    *= other.levels.gamma;\r
-       field_mode                               = static_cast<core::field_mode>(field_mode & other.field_mode);\r
-       is_key                                  |= other.is_key;\r
-       is_mix                                  |= other.is_mix;\r
-       is_still                                |= other.is_still;\r
-       return *this;\r
-}\r
-\r
-image_transform image_transform::operator*(const image_transform &other) const\r
-{\r
-       return image_transform(*this) *= other;\r
-}\r
-\r
-image_transform image_transform::tween(double time, const image_transform& source, const image_transform& dest, double duration, const tweener& tween)\r
-{      \r
-       auto do_tween = [](double time, double source, double dest, double duration, const tweener& tween)\r
-       {\r
-               return tween(time, source, dest-source, duration);\r
-       };\r
-       \r
-       image_transform result; \r
-       result.brightness                       = do_tween(time, source.brightness,                             dest.brightness,                        duration, tween);\r
-       result.contrast                         = do_tween(time, source.contrast,                               dest.contrast,                          duration, tween);\r
-       result.saturation                       = do_tween(time, source.saturation,                             dest.saturation,                        duration, tween);\r
-       result.opacity                          = do_tween(time, source.opacity,                                dest.opacity,                           duration, tween);       \r
-       result.fill_translation[0]      = do_tween(time, source.fill_translation[0],    dest.fill_translation[0],       duration, tween), \r
-       result.fill_translation[1]      = do_tween(time, source.fill_translation[1],    dest.fill_translation[1],       duration, tween);               \r
-       result.fill_scale[0]            = do_tween(time, source.fill_scale[0],                  dest.fill_scale[0],                     duration, tween), \r
-       result.fill_scale[1]            = do_tween(time, source.fill_scale[1],                  dest.fill_scale[1],                     duration, tween);       \r
-       result.clip_translation[0]      = do_tween(time, source.clip_translation[0],    dest.clip_translation[0],       duration, tween), \r
-       result.clip_translation[1]      = do_tween(time, source.clip_translation[1],    dest.clip_translation[1],       duration, tween);               \r
-       result.clip_scale[0]            = do_tween(time, source.clip_scale[0],                  dest.clip_scale[0],                     duration, tween), \r
-       result.clip_scale[1]            = do_tween(time, source.clip_scale[1],                  dest.clip_scale[1],                     duration, tween);\r
-       result.levels.max_input         = do_tween(time, source.levels.max_input,               dest.levels.max_input,          duration, tween);\r
-       result.levels.min_input         = do_tween(time, source.levels.min_input,               dest.levels.min_input,          duration, tween);       \r
-       result.levels.max_output        = do_tween(time, source.levels.max_output,              dest.levels.max_output,         duration, tween);\r
-       result.levels.min_output        = do_tween(time, source.levels.min_output,              dest.levels.min_output,         duration, tween);\r
-       result.levels.gamma                     = do_tween(time, source.levels.gamma,                   dest.levels.gamma,                      duration, tween);\r
-       result.field_mode                       = source.field_mode & dest.field_mode;\r
-       result.is_key                           = source.is_key | dest.is_key;\r
-       result.is_mix                           = source.is_mix | dest.is_mix;\r
-       result.is_still                         = source.is_still | dest.is_still;\r
-       \r
-       return result;\r
-}\r
-\r
-bool operator==(const image_transform& lhs, const image_transform& rhs)\r
-{\r
-       auto eq = [](double lhs, double rhs)\r
-       {\r
-               return std::abs(lhs - rhs) < 5e-8;\r
-       };\r
-\r
-       return \r
-               eq(lhs.opacity, rhs.opacity) &&\r
-               eq(lhs.contrast, rhs.contrast) &&\r
-               eq(lhs.brightness, rhs.brightness) &&\r
-               eq(lhs.saturation, rhs.saturation) &&\r
-               boost::range::equal(lhs.fill_translation, rhs.fill_translation, eq) &&\r
-               boost::range::equal(lhs.fill_scale, rhs.fill_scale, eq) &&\r
-               boost::range::equal(lhs.clip_translation, rhs.clip_translation, eq) &&\r
-               boost::range::equal(lhs.clip_scale, rhs.clip_scale, eq) &&\r
-               lhs.field_mode == rhs.field_mode &&\r
-               lhs.is_key == rhs.is_key &&\r
-               lhs.is_mix == rhs.is_mix &&\r
-               lhs.is_still == rhs.is_still;\r
-}\r
-\r
-bool operator!=(const image_transform& lhs, const image_transform& rhs)\r
-{\r
-       return !(lhs == rhs);\r
-}\r
-\r
-// audio_transform\r
-               \r
-audio_transform::audio_transform() \r
-       : volume(1.0)\r
-       , is_still(false)\r
-{\r
-}\r
-\r
-audio_transform& audio_transform::operator*=(const audio_transform &other)\r
-{\r
-       volume   *= other.volume;       \r
-       is_still |= other.is_still;\r
-       return *this;\r
-}\r
-\r
-audio_transform audio_transform::operator*(const audio_transform &other) const\r
-{\r
-       return audio_transform(*this) *= other;\r
-}\r
-\r
-audio_transform audio_transform::tween(double time, const audio_transform& source, const audio_transform& dest, double duration, const tweener& tween)\r
-{      \r
-       auto do_tween = [](double time, double source, double dest, double duration, const tweener& tween)\r
-       {\r
-               return tween(time, source, dest-source, duration);\r
-       };\r
-       \r
-       audio_transform result; \r
-       result.is_still                 = source.is_still | dest.is_still;\r
-       result.volume                   = do_tween(time, source.volume,                         dest.volume,                    duration, tween);\r
-       \r
-       return result;\r
-}\r
-\r
-bool operator==(const audio_transform& lhs, const audio_transform& rhs)\r
-{\r
-       auto eq = [](double lhs, double rhs)\r
-       {\r
-               return std::abs(lhs - rhs) < 5e-8;\r
-       };\r
-\r
-       return eq(lhs.volume, rhs.volume) && lhs.is_still == rhs.is_still;\r
-}\r
-\r
-bool operator!=(const audio_transform& lhs, const audio_transform& rhs)\r
-{\r
-       return !(lhs == rhs);\r
-}\r
-\r
-// frame_transform\r
-frame_transform::frame_transform()\r
-{\r
-}\r
-\r
-frame_transform& frame_transform::operator*=(const frame_transform &other)\r
-{\r
-       image_transform *= other.image_transform;\r
-       audio_transform *= other.audio_transform;\r
-       return *this;\r
-}\r
-\r
-frame_transform frame_transform::operator*(const frame_transform &other) const\r
-{\r
-       return frame_transform(*this) *= other;\r
-}\r
-\r
-frame_transform frame_transform::tween(double time, const frame_transform& source, const frame_transform& dest, double duration, const tweener& tween)\r
-{\r
-       frame_transform result;\r
-       result.image_transform = image_transform::tween(time, source.image_transform, dest.image_transform, duration, tween);\r
-       result.audio_transform = audio_transform::tween(time, source.audio_transform, dest.audio_transform, duration, tween);\r
-       return result;\r
-}\r
-\r
-bool operator==(const frame_transform& lhs, const frame_transform& rhs)\r
-{\r
-       return  lhs.image_transform == rhs.image_transform && \r
-                       lhs.audio_transform == rhs.audio_transform;\r
-}\r
-\r
-bool operator!=(const frame_transform& lhs, const frame_transform& rhs)\r
-{\r
-       return !(lhs == rhs);\r
-}\r
-\r
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Robert Nagy, ronag89@gmail.com
+*/
+
+#include "../stdafx.h"
+
+#include "frame_transform.h"
+
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/range/algorithm/fill.hpp>
+
+namespace caspar { namespace core {
+               
+// image_transform
+
+image_transform::image_transform() 
+       : opacity(1.0)
+       , brightness(1.0)
+       , contrast(1.0)
+       , saturation(1.0)
+       , field_mode(field_mode::progressive)
+       , is_key(false)
+       , is_mix(false)
+       , is_still(false)
+{
+       boost::range::fill(fill_translation, 0.0);
+       boost::range::fill(fill_scale, 1.0);
+       boost::range::fill(clip_translation, 0.0);
+       boost::range::fill(clip_scale, 1.0);
+}
+
+image_transform& image_transform::operator*=(const image_transform &other)
+{
+       opacity                                 *= other.opacity;       
+       brightness                              *= other.brightness;
+       contrast                                *= other.contrast;
+       saturation                              *= other.saturation;
+       fill_translation[0]             += other.fill_translation[0]*fill_scale[0];
+       fill_translation[1]             += other.fill_translation[1]*fill_scale[1];
+       fill_scale[0]                   *= other.fill_scale[0];
+       fill_scale[1]                   *= other.fill_scale[1];
+       clip_translation[0]             += other.clip_translation[0]*clip_scale[0];
+       clip_translation[1]             += other.clip_translation[1]*clip_scale[1];
+       clip_scale[0]                   *= other.clip_scale[0];
+       clip_scale[1]                   *= other.clip_scale[1];
+       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;
+       field_mode                               = static_cast<core::field_mode>(field_mode & other.field_mode);
+       is_key                                  |= other.is_key;
+       is_mix                                  |= other.is_mix;
+       is_still                                |= other.is_still;
+       return *this;
+}
+
+image_transform image_transform::operator*(const image_transform &other) const
+{
+       return image_transform(*this) *= other;
+}
+
+image_transform image_transform::tween(double time, const image_transform& source, const image_transform& dest, double duration, const tweener& tween)
+{      
+       auto do_tween = [](double time, double source, double dest, double duration, const tweener& tween)
+       {
+               return tween(time, source, dest-source, duration);
+       };
+       
+       image_transform result; 
+       result.brightness                       = do_tween(time, source.brightness,                             dest.brightness,                        duration, tween);
+       result.contrast                         = do_tween(time, source.contrast,                               dest.contrast,                          duration, tween);
+       result.saturation                       = do_tween(time, source.saturation,                             dest.saturation,                        duration, tween);
+       result.opacity                          = do_tween(time, source.opacity,                                dest.opacity,                           duration, tween);       
+       result.fill_translation[0]      = do_tween(time, source.fill_translation[0],    dest.fill_translation[0],       duration, tween), 
+       result.fill_translation[1]      = do_tween(time, source.fill_translation[1],    dest.fill_translation[1],       duration, tween);               
+       result.fill_scale[0]            = do_tween(time, source.fill_scale[0],                  dest.fill_scale[0],                     duration, tween), 
+       result.fill_scale[1]            = do_tween(time, source.fill_scale[1],                  dest.fill_scale[1],                     duration, tween);       
+       result.clip_translation[0]      = do_tween(time, source.clip_translation[0],    dest.clip_translation[0],       duration, tween), 
+       result.clip_translation[1]      = do_tween(time, source.clip_translation[1],    dest.clip_translation[1],       duration, tween);               
+       result.clip_scale[0]            = do_tween(time, source.clip_scale[0],                  dest.clip_scale[0],                     duration, tween), 
+       result.clip_scale[1]            = do_tween(time, source.clip_scale[1],                  dest.clip_scale[1],                     duration, tween);
+       result.levels.max_input         = do_tween(time, source.levels.max_input,               dest.levels.max_input,          duration, tween);
+       result.levels.min_input         = do_tween(time, source.levels.min_input,               dest.levels.min_input,          duration, tween);       
+       result.levels.max_output        = do_tween(time, source.levels.max_output,              dest.levels.max_output,         duration, tween);
+       result.levels.min_output        = do_tween(time, source.levels.min_output,              dest.levels.min_output,         duration, tween);
+       result.levels.gamma                     = do_tween(time, source.levels.gamma,                   dest.levels.gamma,                      duration, tween);
+       result.field_mode                       = source.field_mode & dest.field_mode;
+       result.is_key                           = source.is_key | dest.is_key;
+       result.is_mix                           = source.is_mix | dest.is_mix;
+       result.is_still                         = source.is_still | dest.is_still;
+       
+       return result;
+}
+
+bool operator==(const image_transform& lhs, const image_transform& rhs)
+{
+       auto eq = [](double lhs, double rhs)
+       {
+               return std::abs(lhs - rhs) < 5e-8;
+       };
+
+       return 
+               eq(lhs.opacity, rhs.opacity) &&
+               eq(lhs.contrast, rhs.contrast) &&
+               eq(lhs.brightness, rhs.brightness) &&
+               eq(lhs.saturation, rhs.saturation) &&
+               boost::range::equal(lhs.fill_translation, rhs.fill_translation, eq) &&
+               boost::range::equal(lhs.fill_scale, rhs.fill_scale, eq) &&
+               boost::range::equal(lhs.clip_translation, rhs.clip_translation, eq) &&
+               boost::range::equal(lhs.clip_scale, rhs.clip_scale, eq) &&
+               lhs.field_mode == rhs.field_mode &&
+               lhs.is_key == rhs.is_key &&
+               lhs.is_mix == rhs.is_mix &&
+               lhs.is_still == rhs.is_still;
+}
+
+bool operator!=(const image_transform& lhs, const image_transform& rhs)
+{
+       return !(lhs == rhs);
+}
+
+// audio_transform
+               
+audio_transform::audio_transform() 
+       : volume(1.0)
+       , is_still(false)
+{
+}
+
+audio_transform& audio_transform::operator*=(const audio_transform &other)
+{
+       volume   *= other.volume;       
+       is_still |= other.is_still;
+       return *this;
+}
+
+audio_transform audio_transform::operator*(const audio_transform &other) const
+{
+       return audio_transform(*this) *= other;
+}
+
+audio_transform audio_transform::tween(double time, const audio_transform& source, const audio_transform& dest, double duration, const tweener& tween)
+{      
+       auto do_tween = [](double time, double source, double dest, double duration, const tweener& tween)
+       {
+               return tween(time, source, dest-source, duration);
+       };
+       
+       audio_transform result; 
+       result.is_still                 = source.is_still | dest.is_still;
+       result.volume                   = do_tween(time, source.volume,                         dest.volume,                    duration, tween);
+       
+       return result;
+}
+
+bool operator==(const audio_transform& lhs, const audio_transform& rhs)
+{
+       auto eq = [](double lhs, double rhs)
+       {
+               return std::abs(lhs - rhs) < 5e-8;
+       };
+
+       return eq(lhs.volume, rhs.volume) && lhs.is_still == rhs.is_still;
+}
+
+bool operator!=(const audio_transform& lhs, const audio_transform& rhs)
+{
+       return !(lhs == rhs);
+}
+
+// frame_transform
+frame_transform::frame_transform()
+{
+}
+
+frame_transform& frame_transform::operator*=(const frame_transform &other)
+{
+       image_transform *= other.image_transform;
+       audio_transform *= other.audio_transform;
+       return *this;
+}
+
+frame_transform frame_transform::operator*(const frame_transform &other) const
+{
+       return frame_transform(*this) *= other;
+}
+
+frame_transform frame_transform::tween(double time, const frame_transform& source, const frame_transform& dest, double duration, const tweener& tween)
+{
+       frame_transform result;
+       result.image_transform = image_transform::tween(time, source.image_transform, dest.image_transform, duration, tween);
+       result.audio_transform = audio_transform::tween(time, source.audio_transform, dest.audio_transform, duration, tween);
+       return result;
+}
+
+bool operator==(const frame_transform& lhs, const frame_transform& rhs)
+{
+       return  lhs.image_transform == rhs.image_transform && 
+                       lhs.audio_transform == rhs.audio_transform;
+}
+
+bool operator!=(const frame_transform& lhs, const frame_transform& rhs)
+{
+       return !(lhs == rhs);
+}
+
 }}
\ No newline at end of file