]> git.sesse.net Git - casparcg/commitdiff
#102
authorHelge Norberg <helge.norberg@svt.se>
Fri, 12 Apr 2013 18:39:44 +0000 (20:39 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Fri, 12 Apr 2013 18:39:44 +0000 (20:39 +0200)
Add support for submitting base64 encoded png data to image_consumer

24 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/utility/base64.cpp [new file with mode: 0644]
common/utility/base64.h [new file with mode: 0644]
core/producer/color/color_producer.cpp
core/producer/color/color_producer.h
core/producer/frame_producer.cpp
core/producer/frame_producer.h
core/producer/playlist/playlist_producer.cpp
core/producer/playlist/playlist_producer.h
modules/decklink/producer/decklink_producer.cpp
modules/decklink/producer/decklink_producer.h
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/ffmpeg_producer.h
modules/flash/producer/cg_producer.cpp
modules/flash/producer/cg_producer.h
modules/flash/producer/flash_producer.cpp
modules/flash/producer/flash_producer.h
modules/image/producer/image_producer.cpp
modules/image/producer/image_producer.h
modules/image/producer/image_scroll_producer.cpp
modules/image/producer/image_scroll_producer.h
protocol/amcp/AMCPCommandsImpl.cpp
shell/main.cpp

index 1863a5021954e967a2760915ef0dae65716debf8..4b9a133ccdbe27490ec4465d95505873844b76ad 100644 (file)
     <ClInclude Include="os\windows\system_info.h" />\r
     <ClInclude Include="stdafx.h" />\r
     <ClInclude Include="utility\assert.h" />\r
+    <ClInclude Include="utility\base64.h" />\r
     <ClInclude Include="utility\move_on_copy.h" />\r
     <ClInclude Include="utility\param.h" />\r
     <ClInclude Include="utility\string.h" />\r
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">Create</PrecompiledHeader>\r
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">Create</PrecompiledHeader>\r
     </ClCompile>\r
+    <ClCompile Include="utility\base64.cpp">\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
+    </ClCompile>\r
     <ClCompile Include="utility\string.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
index ae7610cb629ffc11a4a8632473ec27fdbdc2ad52..ee858295a192e6d7de84297b6e0a7981bbe89c12 100644 (file)
@@ -67,6 +67,9 @@
     <ClCompile Include="filesystem\polling_filesystem_monitor.cpp">\r
       <Filter>source\filesystem</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="utility\base64.cpp">\r
+      <Filter>source\utility</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="exception\exceptions.h">\r
     <ClInclude Include="filesystem\polling_filesystem_monitor.h">\r
       <Filter>source\filesystem</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="utility\base64.h">\r
+      <Filter>source\utility</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
diff --git a/common/utility/base64.cpp b/common/utility/base64.cpp
new file mode 100644 (file)
index 0000000..f0e806e
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+* 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: Helge Norberg, helge.norberg@svt.se
+*/
+
+#include "../stdafx.h"
+
+#include "base64.h"
+
+#include <vector>
+#include <algorithm>
+
+#include <boost/archive/iterators/insert_linebreaks.hpp>
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/binary_from_base64.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
+#include <boost/archive/iterators/remove_whitespace.hpp>
+#include <boost/range/join.hpp>
+#include <boost/range/adaptor/sliced.hpp>
+
+#include "../exception/exceptions.h"
+
+namespace caspar {
+
+std::string to_base64(const char* data, size_t length)
+{
+       using namespace boost::archive::iterators;
+
+       // From http://www.webbiscuit.co.uk/2012/04/02/base64-encoder-and-boost/
+               
+       typedef
+               insert_linebreaks<         // insert line breaks every 76 characters
+                       base64_from_binary<    // convert binary values to base64 characters
+                               transform_width<   // retrieve 6 bit integers from a sequence of 8 bit bytes
+                                       const unsigned char *,
+                                       6,
+                                       8
+                               >
+                       >,
+                       76
+               >
+        base64_iterator; // compose all the above operations in to a new iterator
+       std::vector<char> bytes;
+       bytes.resize(length);
+       std::memcpy(bytes.data(), data, length);
+
+       int padding = 0;
+
+       while (bytes.size() % 3 != 0)
+       {
+               ++padding;
+               bytes.push_back(0x00);
+       }
+
+       std::string result(base64_iterator(bytes.data()), base64_iterator(bytes.data() + length - padding));
+       result.insert(result.end(), padding, '=');
+
+       return std::move(result);
+}
+
+std::vector<unsigned char> from_base64(const std::string& data)
+{
+       int padding = 0;
+       std::string zero_padding;
+
+       // binary_from_base64 does not support padding characters so we have to append base64 0 -> 'A' and then remove it after decoding
+       if (data.length() >= 2)
+       {
+               if (data[data.length() - 1] == '=')
+               {
+                       ++padding;
+                       zero_padding += 'A';
+               }
+
+               if (data[data.length() - 2] == '=')
+               {
+                       ++padding;
+                       zero_padding += 'A';
+               }
+       }
+
+       if (padding > 0)
+       {
+               auto concatenated = boost::join(
+                               data | boost::adaptors::sliced(0, data.length() - padding),
+                               boost::make_iterator_range(zero_padding.cbegin(), zero_padding.cend()));
+
+               // From https://svn.boost.org/trac/boost/ticket/5624
+               typedef boost::archive::iterators::transform_width<
+                               boost::archive::iterators::binary_from_base64<
+                                       boost::archive::iterators::remove_whitespace<decltype(concatenated.begin())>
+                               >,
+                               8,
+                               6
+                       > base64_iterator;
+
+               std::vector<unsigned char> result(base64_iterator(concatenated.begin()), base64_iterator(concatenated.end()));
+
+               result.resize(result.size() - padding);
+
+               return std::move(result);
+       }
+       else
+       {
+               // From https://svn.boost.org/trac/boost/ticket/5624
+               typedef boost::archive::iterators::transform_width<
+                               boost::archive::iterators::binary_from_base64<
+                                       boost::archive::iterators::remove_whitespace<std::string::const_iterator>
+                               >,
+                               8,
+                               6
+                       > base64_iterator;
+               std::vector<unsigned char> result(base64_iterator(data.begin()), base64_iterator(data.end()));
+
+               return std::move(result);
+       }
+}
+
+}
diff --git a/common/utility/base64.h b/common/utility/base64.h
new file mode 100644 (file)
index 0000000..6a90a7d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* 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: Helge Norberg, helge.norberg@svt.se
+*/
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+namespace caspar {
+
+std::string to_base64(const char* data, size_t length);
+std::vector<unsigned char> from_base64(const std::string& data);
+
+}
index 8582a27417dd87de1e79d1987cd10aac924b9071..078a10d4fa1f7047ac38a63a86221cedb7d26466 100644 (file)
@@ -113,7 +113,10 @@ std::wstring get_hex_color(const std::wstring& str)
        return str;\r
 }\r
 \r
-safe_ptr<frame_producer> create_color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_color_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
        if(params.size() < 0)\r
                return core::frame_producer::empty();\r
index 56bde5a82fdd53349b293f4c7264864fe6afdcaa..e7b1cfdb459ba4227bb447901d2917d6ac722e3d 100644 (file)
@@ -31,7 +31,10 @@ namespace caspar { namespace core {
 class write_frame;\r
 struct frame_factory;\r
 \r
-safe_ptr<frame_producer> create_color_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_color_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 safe_ptr<core::write_frame> create_color_frame(void* tag, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& color);\r
 \r
 }}\r
index 02cc30f3a3bf409a33dfd257a64dd97d84cacd92..015c2e0e648c93a3ba8a72121cc77d4f9d8bfd11 100644 (file)
@@ -229,9 +229,9 @@ void register_thumbnail_producer_factory(const producer_factory_t& factory)
        g_thumbnail_factories.push_back(factory);\r
 }\r
 \r
-safe_ptr<core::frame_producer> do_create_producer(const safe_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params, const std::vector<const producer_factory_t>& factories, bool throw_on_fail = false)\r
+safe_ptr<core::frame_producer> do_create_producer(const safe_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& upper_case_params, const std::vector<std::wstring>& original_case_params, const std::vector<const producer_factory_t>& factories, bool throw_on_fail = false)\r
 {\r
-       if(params.empty())\r
+       if(upper_case_params.empty())\r
                BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info(""));\r
        \r
        auto producer = frame_producer::empty();\r
@@ -239,7 +239,7 @@ safe_ptr<core::frame_producer> do_create_producer(const safe_ptr<frame_factory>&
                {\r
                        try\r
                        {\r
-                               producer = factory(my_frame_factory, params);\r
+                               producer = factory(my_frame_factory, upper_case_params, original_case_params);\r
                        }\r
                        catch(...)\r
                        {\r
@@ -252,30 +252,34 @@ safe_ptr<core::frame_producer> do_create_producer(const safe_ptr<frame_factory>&
                });\r
 \r
        if(producer == frame_producer::empty())\r
-               producer = create_color_producer(my_frame_factory, params);\r
+               producer = create_color_producer(my_frame_factory, upper_case_params, original_case_params);\r
        \r
        if(producer == frame_producer::empty())\r
-               producer = create_playlist_producer(my_frame_factory, params);\r
+               producer = create_playlist_producer(my_frame_factory, upper_case_params, original_case_params);\r
        \r
        return producer;\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>& my_frame_factory, const std::vector<std::wstring>& upper_case_params, const std::vector<std::wstring>& original_case_params)\r
 {      \r
-       auto producer = do_create_producer(my_frame_factory, params, g_factories);\r
+       auto producer = do_create_producer(my_frame_factory, upper_case_params, original_case_params, g_factories);\r
        auto key_producer = frame_producer::empty();\r
        \r
        try // to find a key file.\r
        {\r
-               auto params_copy = params;\r
-               if(params_copy.size() > 0)\r
+               auto upper_params_copy = upper_case_params;\r
+               auto original_params_copy = original_case_params;\r
+\r
+               if(upper_case_params.size() > 0)\r
                {\r
-                       params_copy[0] += L"_A";\r
-                       key_producer = do_create_producer(my_frame_factory, params_copy, g_factories);                  \r
+                       upper_params_copy[0] += L"_A";\r
+                       original_params_copy[0] += L"_A";\r
+                       key_producer = do_create_producer(my_frame_factory, upper_params_copy, original_params_copy, g_factories);                      \r
                        if(key_producer == frame_producer::empty())\r
                        {\r
-                               params_copy[0] += L"LPHA";\r
-                               key_producer = do_create_producer(my_frame_factory, params_copy, g_factories);  \r
+                               upper_params_copy[0] += L"LPHA";\r
+                               original_params_copy[0] += L"LPHA";\r
+                               key_producer = do_create_producer(my_frame_factory, upper_params_copy, original_params_copy, g_factories);      \r
                        }\r
                }\r
        }\r
@@ -287,7 +291,7 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>& my
        if(producer == frame_producer::empty())\r
        {\r
                std::wstring str;\r
-               BOOST_FOREACH(auto& param, params)\r
+               BOOST_FOREACH(auto& param, original_case_params)\r
                        str += param + L" ";\r
                BOOST_THROW_EXCEPTION(file_not_found() << msg_info("No match found for supplied commands. Check syntax.") << arg_value_info(narrow(str)));\r
        }\r
@@ -300,7 +304,7 @@ safe_ptr<core::frame_producer> create_thumbnail_producer(const safe_ptr<frame_fa
        std::vector<std::wstring> params;\r
        params.push_back(media_file);\r
 \r
-       auto producer = do_create_producer(my_frame_factory, params, g_thumbnail_factories, true);\r
+       auto producer = do_create_producer(my_frame_factory, params, params, g_thumbnail_factories, true);\r
        auto key_producer = frame_producer::empty();\r
        \r
        try // to find a key file.\r
@@ -309,11 +313,11 @@ safe_ptr<core::frame_producer> create_thumbnail_producer(const safe_ptr<frame_fa
                if (params_copy.size() > 0)\r
                {\r
                        params_copy[0] += L"_A";\r
-                       key_producer = do_create_producer(my_frame_factory, params_copy, g_thumbnail_factories, true);\r
+                       key_producer = do_create_producer(my_frame_factory, params_copy, params_copy, g_thumbnail_factories, true);\r
                        if (key_producer == frame_producer::empty())\r
                        {\r
                                params_copy[0] += L"LPHA";\r
-                               key_producer = do_create_producer(my_frame_factory, params_copy, g_thumbnail_factories, true);\r
+                               key_producer = do_create_producer(my_frame_factory, params_copy, params_copy, g_thumbnail_factories, true);\r
                        }\r
                }\r
        }\r
@@ -331,7 +335,7 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>& fa
        std::vector<std::wstring> tokens;\r
        typedef std::istream_iterator<std::wstring, wchar_t, std::char_traits<wchar_t> > iterator;\r
        std::copy(iterator(iss),  iterator(), std::back_inserter(tokens));\r
-       return create_producer(factory, tokens);\r
+       return create_producer(factory, tokens, tokens);\r
 }\r
 \r
 }}
\ No newline at end of file
index a29e78d03a175fe224d5a4a3de7c54c5beef3be8..64640718f364fe022d5ca17f76a3d26ba1946cde 100644 (file)
@@ -79,10 +79,10 @@ public:
 \r
 safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer, int hints);\r
 \r
-typedef std::function<safe_ptr<core::frame_producer>(const safe_ptr<frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
+typedef std::function<safe_ptr<core::frame_producer>(const safe_ptr<frame_factory>&, const std::vector<std::wstring>& upper_case_params, const std::vector<std::wstring>& original_case_params)> producer_factory_t;\r
 void register_producer_factory(const producer_factory_t& factory); // Not thread-safe.\r
 void register_thumbnail_producer_factory(const producer_factory_t& factory); // Not thread-safe.\r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>&, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>&, const std::vector<std::wstring>& upper_case_params, const std::vector<std::wstring>& original_case_params);\r
 safe_ptr<core::frame_producer> create_producer(const safe_ptr<frame_factory>&, const std::wstring& params);\r
 safe_ptr<core::frame_producer> create_producer_destroy_proxy(safe_ptr<core::frame_producer> producer);\r
 safe_ptr<core::frame_producer> create_producer_print_proxy(safe_ptr<core::frame_producer> producer);\r
index 2068e2a57c4969611e4a2e4532ee8ac4dfc66ec3..b84764d21323018ee224d86c753fe4b487e15efb 100644 (file)
@@ -208,7 +208,10 @@ struct playlist_producer : public frame_producer
        }\r
 };\r
 \r
-safe_ptr<frame_producer> create_playlist_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<frame_producer> create_playlist_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
        if(boost::range::find(params, L"[PLAYLIST]") == params.end())\r
                return core::frame_producer::empty();\r
index 23c130c3f000115ad382ad501fd0f2b8124ca760..9d9cf876df689ec4524635c5db6c88d44ea9c832 100644 (file)
@@ -29,6 +29,9 @@
 \r
 namespace caspar { namespace core {\r
        \r
-safe_ptr<frame_producer> create_playlist_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<frame_producer> create_playlist_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 }}
\ No newline at end of file
index 2723a6489326ce49d75c7749b9cc7671cf89b1f0..6e9158bdffc43cc1ac05c320122f447704702334 100644 (file)
@@ -322,7 +322,10 @@ public:
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
        if(params.empty() || !boost::iequals(params[0], "decklink"))\r
                return core::frame_producer::empty();\r
index a190ec58e862f44d24ff9872e533aa3371fd642f..bd9cae92cc535f43caf43bfbe7463e4c48728f6b 100644 (file)
@@ -28,6 +28,9 @@
 \r
 namespace caspar { namespace decklink {\r
        \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 }}\r
index e5b03432121fe83210e2220da6089f57b3ea888f..d1a0d8c5413af80a742eefabd8e3e1dc9d94fe7d 100644 (file)
@@ -422,7 +422,10 @@ public:
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {              \r
        static const std::vector<std::wstring> invalid_exts = boost::assign::list_of(L".png")(L".tga")(L".bmp")(L".jpg")(L".jpeg")(L".gif")(L".tiff")(L".tif")(L".jp2")(L".jpx")(L".j2k")(L".j2c")(L".swf")(L".ct");\r
        auto filename = probe_stem(env::media_folder() + L"\\" + params.at(0), invalid_exts);\r
@@ -441,7 +444,10 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factor
        return create_producer_destroy_proxy(make_safe<ffmpeg_producer>(frame_factory, filename, filter_str, loop, start, length, false));\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_thumbnail_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_thumbnail_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {              \r
        static const std::vector<std::wstring> invalid_exts = boost::assign::list_of\r
                        (L".png")(L".tga")(L".bmp")(L".jpg")(L".jpeg")(L".gif")(L".tiff")(L".tif")(L".jp2")(L".jpx")(L".j2k")(L".j2c")(L".swf")(L".ct")\r
index 66aaf71d88115b895e5042f6f8f12ca801e02274..c27e60f1c42e4203c24bf75daff4d995cfb7e1fd 100644 (file)
@@ -37,7 +37,13 @@ struct frame_factory;
        \r
 namespace ffmpeg {\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
-safe_ptr<core::frame_producer> create_thumbnail_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
+safe_ptr<core::frame_producer> create_thumbnail_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 }}
\ No newline at end of file
index e49cf2fd7830af256575e95459135588ca66dcfb..661a4cf9dd5a61e4ff0b3a15798373f693c48591 100644 (file)
@@ -234,12 +234,18 @@ safe_ptr<core::frame_producer> create_cg_producer_and_autoplay_file(
        return producer;\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params) \r
+safe_ptr<core::frame_producer> create_ct_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params) \r
 {\r
        return create_cg_producer_and_autoplay_file(frame_factory, params, env::media_folder() + L"\\" + params[0] + L".ct");\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_cg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params) \r
+safe_ptr<core::frame_producer> create_cg_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params) \r
 {\r
        if(params.empty() || params.at(0) != L"[CG]")\r
                return core::frame_producer::empty();\r
index 875b3cf303d2630832b1311425b824c69024de91..bab1dc58bebf24db230ec15796fad88c4503bcd8 100644 (file)
@@ -66,7 +66,13 @@ private:
 };\r
 safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::video_channel>& video_channel, int layer_index = cg_producer::DEFAULT_LAYER);\r
 \r
-safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
-safe_ptr<core::frame_producer> create_cg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_ct_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
+safe_ptr<core::frame_producer> create_cg_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 }}
\ No newline at end of file
index 7afb1bdfdd1f9d097acfbd241cf7a054e9ab5c44..72a8720bfe9841d486e0ce7be8abc8334aa5af8a 100644 (file)
@@ -504,7 +504,10 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factor
                        make_safe<flash_producer>(frame_factory, filename, template_host.width, template_host.height)));\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_swf_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params) \r
+safe_ptr<core::frame_producer> create_swf_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params) \r
 {\r
        auto filename = env::media_folder() + L"\\" + params.at(0) + L".swf";\r
        \r
index fec8d1699926ffa7a5c83729d99b0cc797181f5e..e4f37fe9a845f59a2680b0976e1c5328d185e934 100644 (file)
 namespace caspar { namespace flash {\r
 \r
 safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
-safe_ptr<core::frame_producer> create_swf_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_swf_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 std::wstring find_template(const std::wstring& templateName);\r
 \r
index 0f562bc2ce17a61c54932b36abfd269aadcc7ea5..6c01f315abbd506e68777da8f2a645f55267242f 100644 (file)
@@ -31,6 +31,8 @@
 \r
 #include <common/env.h>\r
 #include <common/log/log.h>\r
+#include <common/utility/base64.h>\r
+#include <common/utility/string.h>\r
 \r
 #include <boost/assign.hpp>\r
 #include <boost/filesystem.hpp>\r
@@ -44,26 +46,40 @@ namespace caspar { namespace image {
 \r
 struct image_producer : public core::frame_producer\r
 {      \r
-       const std::wstring filename_;\r
+       const std::wstring description_;\r
+       const safe_ptr<core::frame_factory> frame_factory_;\r
        safe_ptr<core::basic_frame> frame_;\r
        \r
        explicit image_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) \r
-               : filename_(filename)\r
+               : description_(filename)\r
+               , frame_factory_(frame_factory)\r
                , frame_(core::basic_frame::empty())    \r
        {\r
-               auto bitmap = load_image(filename_);\r
+               load(load_image(filename));\r
+       }\r
+\r
+       explicit image_producer(const safe_ptr<core::frame_factory>& frame_factory, const void* png_data, size_t size)\r
+               : description_(L"png from memory")\r
+               , frame_factory_(frame_factory)\r
+               , frame_(core::basic_frame::empty())\r
+       {\r
+               load(load_png_from_memory(png_data, size));\r
+       }\r
+\r
+       void load(const std::shared_ptr<FIBITMAP>& bitmap)\r
+       {\r
                FreeImage_FlipVertical(bitmap.get());\r
-               \r
+\r
                core::pixel_format_desc desc;\r
                desc.pix_fmt = core::pixel_format::bgra;\r
                desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4));\r
-               auto frame = frame_factory->create_frame(this, desc);\r
+               auto frame = frame_factory_->create_frame(this, desc);\r
 \r
                std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data().size(), frame->image_data().begin());\r
                frame->commit();\r
                frame_ = std::move(frame);\r
        }\r
-       \r
+\r
        // frame_producer\r
 \r
        virtual safe_ptr<core::basic_frame> receive(int) override\r
@@ -83,20 +99,32 @@ struct image_producer : public core::frame_producer
                \r
        virtual std::wstring print() const override\r
        {\r
-               return L"image_producer[" + filename_ + L"]";\r
+               return L"image_producer[" + description_ + L"]";\r
        }\r
 \r
        virtual boost::property_tree::wptree info() const override\r
        {\r
                boost::property_tree::wptree info;\r
                info.add(L"type", L"image-producer");\r
-               info.add(L"filename", filename_);\r
+               info.add(L"location", description_);\r
                return info;\r
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_raw_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_raw_producer(const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
+       if (params[0] == L"[PNG_BASE64]")\r
+       {\r
+               if (params.size() < 2)\r
+                       return core::frame_producer::empty();\r
+\r
+               auto png_data = from_base64(narrow(original_case_params[1]));\r
+\r
+               return make_safe<image_producer>(frame_factory, png_data.data(), png_data.size());\r
+       }\r
+\r
        static const std::vector<std::wstring> extensions = list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg")(L"gif")(L"tiff")(L"tif")(L"jp2")(L"jpx")(L"j2k")(L"j2c");\r
        std::wstring filename = env::media_folder() + L"\\" + params[0];\r
        \r
@@ -111,9 +139,12 @@ safe_ptr<core::frame_producer> create_raw_producer(const safe_ptr<core::frame_fa
        return make_safe<image_producer>(frame_factory, filename + L"." + *ext);\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
-       auto raw_producer = create_raw_producer(frame_factory, params);\r
+       auto raw_producer = create_raw_producer(frame_factory, params, original_case_params);\r
 \r
        if (raw_producer == core::frame_producer::empty())\r
                return raw_producer;\r
@@ -121,9 +152,12 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factor
        return create_producer_print_proxy(raw_producer);\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_thumbnail_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_thumbnail_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
-       return create_raw_producer(frame_factory, params);\r
+       return create_raw_producer(frame_factory, params, original_case_params);\r
 }\r
 \r
 }}
\ No newline at end of file
index 3d95d080fe4f58fa5414debbf2f0e8326783593f..2886836278f1b2f1c1665b0f1a422eca05f604d1 100644 (file)
 \r
 namespace caspar { namespace image {\r
 \r
-safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
-safe_ptr<core::frame_producer> create_thumbnail_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
+safe_ptr<core::frame_producer> create_thumbnail_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 }}
\ No newline at end of file
index 558900e739d060be17179129ba9e697a8b34de02..75815a517fe07881413100892db7927e26246510 100644 (file)
@@ -383,7 +383,10 @@ struct image_scroll_producer : public core::frame_producer
        }\r
 };\r
 \r
-safe_ptr<core::frame_producer> create_scroll_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r
+safe_ptr<core::frame_producer> create_scroll_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params)\r
 {\r
        static const std::vector<std::wstring> extensions = list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg")(L"gif")(L"tiff")(L"tif")(L"jp2")(L"jpx")(L"j2k")(L"j2c");\r
        std::wstring filename = env::media_folder() + L"\\" + params[0];\r
index 42d2a7d28bc82807593e883db35e2816333a2009..08b083fc36385533863ce4449bb62d2c94d158eb 100644 (file)
@@ -28,6 +28,9 @@
 \r
 namespace caspar { namespace image {\r
 \r
-safe_ptr<core::frame_producer> create_scroll_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_scroll_producer(\r
+               const safe_ptr<core::frame_factory>& frame_factory,\r
+               const std::vector<std::wstring>& params,\r
+               const std::vector<std::wstring>& original_case_params);\r
 \r
 }}
\ No newline at end of file
index 0ddd6ff8bdd891c5a81329d487cbff7d7e8bc33e..32d0e7afc326d7b8775d10ef00863ba8747a4326 100644 (file)
@@ -36,6 +36,7 @@
 #include <common/os/windows/system_info.h>\r
 #include <common/utility/string.h>\r
 #include <common/utility/utf8conv.h>\r
+#include <common/utility/base64.h>\r
 \r
 #include <core/producer/frame_producer.h>\r
 #include <core/video_format.h>\r
@@ -117,37 +118,12 @@ std::wstring read_file_base64(const boost::filesystem::wpath& file)
        if (!filestream)\r
                return L"";\r
 \r
-       // From http://www.webbiscuit.co.uk/2012/04/02/base64-encoder-and-boost/\r
-               \r
-       typedef\r
-               insert_linebreaks<         // insert line breaks every 76 characters\r
-                       base64_from_binary<    // convert binary values to base64 characters\r
-                               transform_width<   // retrieve 6 bit integers from a sequence of 8 bit bytes\r
-                                       const unsigned char *,\r
-                                       6,\r
-                                       8\r
-                               >\r
-                       >,\r
-                       76\r
-               >\r
-        base64_iterator; // compose all the above operations in to a new iterator\r
        auto length = boost::filesystem::file_size(file);\r
        std::vector<char> bytes;\r
        bytes.resize(length);\r
        filestream.read(bytes.data(), length);\r
 \r
-       int padding = 0;\r
-\r
-       while (bytes.size() % 3 != 0)\r
-       {\r
-               ++padding;\r
-               bytes.push_back(0x00);\r
-       }\r
-\r
-       std::string result(base64_iterator(bytes.data()), base64_iterator(bytes.data() + length - padding));\r
-       result.insert(result.end(), padding, '=');\r
-\r
-       return widen(result);\r
+       return widen(to_base64(bytes.data(), length));\r
 }\r
 \r
 std::wstring read_utf8_file(const boost::filesystem::wpath& file)\r
@@ -775,7 +751,7 @@ bool LoadCommand::DoExecute()
        try\r
        {\r
                _parameters[0] = _parameters[0];\r
-               auto pFP = create_producer(GetChannel()->mixer(), _parameters);         \r
+               auto pFP = create_producer(GetChannel()->mixer(), _parameters, _parameters2);           \r
                GetChannel()->stage()->load(GetLayerIndex(), pFP, true);\r
        \r
                SetReplyString(TEXT("202 LOAD OK\r\n"));\r
@@ -881,7 +857,7 @@ bool LoadbgCommand::DoExecute()
        try\r
        {\r
                _parameters[0] = _parameters[0];\r
-               auto pFP = create_producer(GetChannel()->mixer(), _parameters);\r
+               auto pFP = create_producer(GetChannel()->mixer(), _parameters, _parameters2);\r
                if(pFP == frame_producer::empty())\r
                        BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? narrow(_parameters[0]) : ""));\r
 \r
@@ -897,7 +873,7 @@ bool LoadbgCommand::DoExecute()
        catch(file_not_found&)\r
        {               \r
                std::wstring params2;\r
-               for(auto it = _parameters.begin(); it != _parameters.end(); ++it)\r
+               for(auto it = _parameters2.begin(); it != _parameters2.end(); ++it)\r
                        params2 += L" " + *it;\r
                CASPAR_LOG(error) << L"File not found. No match found for parameters. Check syntax:" << params2;\r
                SetReplyString(TEXT("404 LOADBG ERROR\r\n"));\r
@@ -938,7 +914,7 @@ bool PlayCommand::DoExecute()
                        lbg.SetChannelIndex(GetChannelIndex());\r
                        lbg.SetLayerIntex(GetLayerIndex());\r
                        lbg.SetClientInfo(GetClientInfo());\r
-                       for(auto it = _parameters.begin(); it != _parameters.end(); ++it)\r
+                       for(auto it = _parameters2.begin(); it != _parameters2.end(); ++it)\r
                                lbg.AddParameter(*it);\r
                        if(!lbg.Execute())\r
                                throw std::exception();\r
index a41f3857b28e91b74c528cbdd2af90700e63ffa7..4dafde22c66fb7865afa03c1ceda8eb7fdada841 100644 (file)
@@ -177,9 +177,9 @@ LONG WINAPI UserUnhandledExceptionFilter(EXCEPTION_POINTERS* info)
     return EXCEPTION_EXECUTE_HANDLER;\r
 }\r
 \r
-void make_upper_case(std::wstring& str)\r
+std::wstring make_upper_case(const std::wstring& str)\r
 {\r
-       boost::to_upper(str);\r
+       return boost::to_upper_copy(str);\r
 }\r
 \r
 int main(int argc, wchar_t* argv[])\r
@@ -287,9 +287,9 @@ int main(int argc, wchar_t* argv[])
                                        std::getline(std::wcin, wcmd); // TODO: It's blocking...\r
                                \r
                                        //boost::to_upper(wcmd);  // TODO COMPILER crashes on this line, Strange!\r
-                                       make_upper_case(wcmd);\r
+                                       auto upper_cmd = make_upper_case(wcmd);\r
 \r
-                                       if(wcmd == L"EXIT" || wcmd == L"Q" || wcmd == L"QUIT" || wcmd == L"BYE")\r
+                                       if(upper_cmd == L"EXIT" || upper_cmd == L"Q" || upper_cmd == L"QUIT" || upper_cmd == L"BYE")\r
                                        {\r
                                                shutdown_server_now.set_value(true); // True to wait for keypress\r
                                                break;\r
@@ -316,7 +316,7 @@ int main(int argc, wchar_t* argv[])
                                                                        L"PLAY 2-2 " + file + L" LOOP\r\n" \r
                                                                        L"PLAY 2-3 " + file + L" LOOP\r\n";\r
                                                }\r
-                                               else if(wcmd.substr(0, 1) == L"X")\r
+                                               else if(upper_cmd.substr(0, 1) == L"X")\r
                                                {\r
                                                        int num = 0;\r
                                                        std::wstring file;\r