1 //#include "image_scroll_producer.h"
\r
3 //#include "image_loader.h"
\r
5 //#include "../../mixer/draw_frame.h"
\r
6 //#include "../../mixer/draw_frame.h"
\r
7 //#include "../../video_format.h"
\r
8 //#include "../../mixer/frame_mixer_device.h"
\r
9 //#include "../../configuration.h"
\r
11 //#include <tbb/parallel_for.h>
\r
12 //#include <tbb/parallel_invoke.h>
\r
13 //#include <tbb/scalable_allocator.h>
\r
15 //#include <boost/assign.hpp>
\r
16 //#include <boost/algorithm/string/case_conv.hpp>
\r
18 //using namespace boost::assign;
\r
20 //namespace caspar { namespace core { namespace image{
\r
24 // Up, Down, Left, Right
\r
27 //struct image_scroll_producer : public frame_producer
\r
29 // static const int DEFAULT_SCROLL_SPEED = 50;
\r
31 // image_scroll_producer(const std::wstring& filename, const std::vector<std::wstring>& params)
\r
32 // : speed_(image_scroll_producer::DEFAULT_SCROLL_SPEED), direction_(direction::Up), offset_(0), filename_(filename)
\r
34 // auto pos = filename.find_last_of(L'_');
\r
35 // if(pos != std::wstring::npos && pos + 1 < filename.size())
\r
37 // std::wstring speedStr = filename.substr(pos + 1);
\r
38 // pos = speedStr.find_first_of(L'.');
\r
39 // if(pos != std::wstring::npos)
\r
41 // speedStr = speedStr.substr(0, pos);
\r
42 // speed_ = lexical_cast_or_default<int>(speedStr, image_scroll_producer::DEFAULT_SCROLL_SPEED);
\r
46 // loop_ = std::find(params.begin(), params.end(), L"LOOP") != params.end();
\r
49 // void load_and_pad_image(const std::wstring& filename)
\r
51 // auto pBitmap = load_image(filename);
\r
53 // size_t width = FreeImage_GetWidth(pBitmap.get());
\r
54 // size_t height = FreeImage_GetHeight(pBitmap.get());
\r
56 // image_width_ = std::max(width, format_desc_.width);
\r
57 // image_height_ = std::max(height, format_desc_.height);
\r
59 // image_ = std::shared_ptr<unsigned char>(static_cast<unsigned char*>(scalable_aligned_malloc(image_width_*image_height_*4, 16)));
\r
60 // std::fill_n(image_.get(), image_width_*image_height_*4, 0);
\r
62 // unsigned char* pBits = FreeImage_GetBits(pBitmap.get());
\r
64 // for (size_t i = 0; i < height; ++i)
\r
65 // std::copy_n(&pBits[i* width * 4], width * 4, &image_.get()[i * image_width_ * 4]);
\r
68 // draw_frame do_receive()
\r
70 // auto frame = frame_factory_->create_frame(format_desc_.width, format_desc_.height);
\r
71 // std::fill(frame.image_data().begin(), frame.image_data().end(), 0);
\r
73 // const int delta_x = direction_ == direction::Left ? speed_ : -speed_;
\r
74 // const int delta_y = direction_ == direction::Up ? speed_ : -speed_;
\r
76 // unsigned char* frame_data = frame.image_data().begin();
\r
77 // unsigned char* image_data = image_.get();
\r
79 // if (direction_ == direction::Up || direction_ == direction::Down)
\r
81 // tbb::parallel_for(static_cast<size_t>(0), format_desc_.height, static_cast<size_t>(1), [&](size_t i)
\r
83 // int srcRow = i + offset_;
\r
84 // int dstInxex = i * format_desc_.width * 4;
\r
85 // int srcIndex = srcRow * format_desc_.width * 4;
\r
86 // int size = format_desc_.width * 4;
\r
88 // std::copy_n(&image_data[srcIndex], size, &frame_data[dstInxex]);
\r
91 // offset_ += delta_y;
\r
95 // tbb::parallel_for(static_cast<size_t>(0), format_desc_.height, static_cast<size_t>(1), [&](size_t i)
\r
97 // int correctOffset = offset_;
\r
98 // int dstIndex = i * format_desc_.width * 4;
\r
99 // int srcIndex = (i * image_width_ + correctOffset) * 4;
\r
101 // int stopOffset = std::min<int>(correctOffset + format_desc_ .width, image_width_);
\r
102 // int size = (stopOffset - correctOffset) * 4;
\r
104 // std::copy_n(&image_data[srcIndex], size, &frame_data[dstIndex]);
\r
107 // offset_ += delta_x;
\r
110 // return std::move(frame);
\r
113 // safe_ptr<draw_frame> receive()
\r
115 // if(format_desc_.mode != video_mode::progressive)
\r
117 // draw_frame frame1;
\r
118 // draw_frame frame2;
\r
119 // tbb::parallel_invoke([&]{ frame1 = std::move(do_receive()); }, [&]{ frame2 = std::move(do_receive()); });
\r
120 // return draw_frame::interlace(std::move(frame1), std::move(frame2), format_desc_.mode);
\r
123 // return receive();
\r
126 // void initialize(const safe_ptr<frame_factory>& frame_factory)
\r
128 // frame_factory_ = frame_factory;
\r
129 // format_desc_ = frame_factory_->get_video_format_desc();
\r
131 // if(image_width_ - format_desc_.width > image_height_ - format_desc_.height)
\r
132 // direction_ = speed_ < 0 ? direction::Right : direction::Left;
\r
134 // direction_ = speed_ < 0 ? direction::Down : direction::Up;
\r
136 // if (direction_ == direction::Down)
\r
137 // offset_ = image_height_ - format_desc_.height;
\r
138 // else if (direction_ == direction::Right)
\r
139 // offset_ = image_width_ - format_desc_.width;
\r
141 // speed_ = static_cast<int>(abs(static_cast<double>(speed_) / format_desc_.fps));
\r
143 // load_and_pad_image(filename_);
\r
147 // std::wstring print() const
\r
149 // return L"image_scroll_producer. filename: " + filename_;
\r
152 // const video_format_desc& get_video_format_desc() const { return format_desc_; }
\r
154 // int image_width_;
\r
155 // int image_height_;
\r
158 // direction direction_;
\r
160 // tbb::atomic<bool> loop_;
\r
161 // std::shared_ptr<unsigned char> image_;
\r
162 // video_format_desc format_desc_;
\r
164 // std::wstring filename_;
\r
166 // safe_ptr<frame_mixer_device> frame_factory_;
\r
169 //safe_ptr<frame_producer> create_image_scroll_producer(const std::vector<std::wstring>& params)
\r
171 // static const std::vector<std::wstring> extensions = list_of(L"spng")(L"stga")(L"sbmp")(L"sjpg")(L"sjpeg");
\r
172 // std::wstring filename = configuration::media_folder() + L"\\" + params[0];
\r
174 // auto ext = std::find_if(extensions.begin(), extensions.end(), [&](const std::wstring& ex) -> bool
\r
176 // return boost::filesystem::is_regular_file(boost::filesystem::wpath(filename).replace_extension(ex));
\r
179 // if(ext == extensions.end())
\r
182 // return std::make_shared<image_scroll_producer>(filename + L"." + *ext, params);
\r