--- /dev/null
+/*
+* 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 "except.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);
+ }
+}
+
+}
\ No newline at end of file
--- /dev/null
+/*
+* 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);
+
+}
\ No newline at end of file
<ItemGroup>\r
<ClInclude Include="array.h" />\r
<ClInclude Include="assert.h" />\r
+ <ClInclude Include="base64.h" />\r
<ClInclude Include="blocking_bounded_queue_adapter.h" />\r
<ClInclude Include="blocking_priority_queue.h" />\r
<ClInclude Include="compiler\vs\disable_silly_warnings.h" />\r
<ClInclude Include="utf.h" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClCompile Include="base64.cpp">\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Develop|x64'">Use</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">Use</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>\r
+ </ClCompile>\r
<ClCompile Include="compiler\vs\stack_walker.cpp">\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Develop|x64'">NotUsing</PrecompiledHeader>\r
<ClCompile Include="polling_filesystem_monitor.cpp">\r
<Filter>source</Filter>\r
</ClCompile>\r
+ <ClCompile Include="base64.cpp">\r
+ <Filter>source</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="compiler\vs\disable_silly_warnings.h">\r
<ClInclude Include="polling_filesystem_monitor.h">\r
<Filter>source</Filter>\r
</ClInclude>\r
+ <ClInclude Include="base64.h">\r
+ <Filter>source</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
try // to find a key file.
{
- auto params_copy = params;
- if (params_copy.size() > 0)
- {
- params_copy[0] += L"_A";
- key_producer = do_create_producer(my_frame_factory, format_desc, params_copy, g_thumbnail_factories, true);
- if (key_producer == frame_producer::empty())
- {
- params_copy[0] += L"LPHA";
- key_producer = do_create_producer(my_frame_factory, format_desc, params_copy, g_thumbnail_factories, true);
- }
- }
+ auto params_copy = params;
+ if (params_copy.size() > 0)
+ {
+ params_copy[0] += L"_A";
+ key_producer = do_create_producer(my_frame_factory, format_desc, params_copy, g_thumbnail_factories, true);
+ if (key_producer == frame_producer::empty())
+ {
+ params_copy[0] += L"LPHA";
+ key_producer = do_create_producer(my_frame_factory, format_desc, params_copy, g_thumbnail_factories, true);
+ }
+ }
}
catch(...){}
if (producer != frame_producer::empty() && key_producer != frame_producer::empty())
- return create_separated_producer(producer, key_producer);
+ return create_separated_producer(producer, key_producer);
return producer;
}
#include <common/env.h>
#include <common/log.h>
#include <common/array.h>
+#include <common/base64.h>
#include <boost/assign.hpp>
#include <boost/filesystem.hpp>
struct image_producer : public core::frame_producer_base
{
monitor::basic_subject event_subject_;
- const std::wstring filename_;
+ const std::wstring description_;
+ const spl::shared_ptr<core::frame_factory> frame_factory_;
core::draw_frame frame_;
core::constraints constraints_;
- explicit image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename)
- : filename_(filename)
+ image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& description)
+ : description_(description)
+ , frame_factory_(frame_factory)
, frame_(core::draw_frame::empty())
{
- auto frame = load_image(frame_factory, filename);
+ load(load_image(description_));
- frame_ = frame.first;
- constraints_ = frame.second;
+ CASPAR_LOG(info) << print() << L" Initialized";
+ }
+
+ image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const void* png_data, size_t size)
+ : description_(L"png from memory")
+ , frame_factory_(frame_factory)
+ , frame_(core::draw_frame::empty())
+ {
+ load(load_png_from_memory(png_data, size));
CASPAR_LOG(info) << print() << L" Initialized";
}
+
+ void load(const std::shared_ptr<FIBITMAP>& bitmap)
+ {
+ FreeImage_FlipVertical(bitmap.get());
+ core::pixel_format_desc desc;
+ desc.format = core::pixel_format::bgra;
+ desc.planes.push_back(core::pixel_format_desc::plane(FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get()), 4));
+ auto frame = frame_factory_->create_frame(this, desc);
+
+ std::copy_n(FreeImage_GetBits(bitmap.get()), frame.image_data().size(), frame.image_data().begin());
+ frame_ = core::draw_frame(std::move(frame));
+ }
// frame_producer
core::draw_frame receive_impl() override
{
- event_subject_ << monitor::event("file/path") % filename_;
+ event_subject_ << monitor::event("file/path") % description_;
return frame_;
}
std::wstring print() const override
{
- return L"image_producer[" + filename_ + L"]";
+ return L"image_producer[" + description_ + L"]";
}
std::wstring name() const override
{
boost::property_tree::wptree info;
info.add(L"type", L"image");
- info.add(L"filename", filename_);
+ info.add(L"location", description_);
return info;
}
return core::create_const_producer(std::move(frames), width, height);
}
+ else if(boost::iequals(params[0], L"[PNG_BASE64]"))
+ {
+ if (params.size() < 2)
+ return core::frame_producer::empty();
+
+ auto png_data = from_base64(std::string(params[1].begin(), params[1].end()));
+
+ return spl::make_shared<image_producer>(frame_factory, png_data.data(), png_data.size());
+ }
std::wstring filename = env::media_folder() + params[0];
#include <common/diagnostics/graph.h>
#include <common/os/windows/current_version.h>
#include <common/os/windows/system_info.h>
+#include <common/base64.h>
#include <core/producer/frame_producer.h>
#include <core/video_format.h>
if (!filestream)
return L"";
- // 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
auto length = boost::filesystem::file_size(file);
std::vector<char> bytes;
bytes.resize(length);
filestream.read(bytes.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, '=');
-
+ std::string result(to_base64(bytes.data(), length));
return std::wstring(result.begin(), result.end());
}
{\r
input_ += data;\r
\r
- std::vector<std::basic_string<CharT>> split;\r
- boost::iter_split(split, input_, boost::algorithm::first_finder(delimiter_)); //TODO: check if this splits on all instances of delimiter_ in the input_\r
+ //boost::iter_split(split, input_, boost::algorithm::first_finder(delimiter_)) was painfully slow in debug-build\r
\r
- input_ = std::move(split.back());\r
- split.pop_back();\r
-\r
- BOOST_FOREACH(auto cmd, split)\r
+ auto delim_pos = input_.find_first_of(delimiter_);\r
+ while(delim_pos != std::string::npos)\r
{\r
- // TODO: perhaps it would be better to not append the delimiter.\r
- strategy_->parse(cmd);\r
+ strategy_->parse(input_.substr(0, delim_pos));\r
+\r
+ input_ = std::move(input_.substr(delim_pos+delimiter_.size()));\r
+ delim_pos = input_.find_first_of(delimiter_);\r
}\r
}\r
};\r