From: Helge Norberg Date: Wed, 15 Mar 2017 18:56:08 +0000 (+0100) Subject: [image_producer] #558 Fixed inconsistency in what file extensions are supported and... X-Git-Tag: 2.1.0_Beta2~44 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;ds=sidebyside;h=a67a2a393dbd8845b838eba70cbf9a7fc92c8e57;p=casparcg [image_producer] #558 Fixed inconsistency in what file extensions are supported and listed in CLS/CINF --- diff --git a/modules/image/image.cpp b/modules/image/image.cpp index a03b01e24..2b6eeeef5 100644 --- a/modules/image/image.cpp +++ b/modules/image/image.cpp @@ -24,6 +24,7 @@ #include "producer/image_producer.h" #include "producer/image_scroll_producer.h" #include "consumer/image_consumer.h" +#include "util/image_loader.h" #include #include @@ -35,6 +36,7 @@ #include #include +#include #include @@ -54,13 +56,7 @@ void init(core::module_dependencies dependencies) dependencies.consumer_registry->register_consumer_factory(L"Image Consumer", create_consumer, describe_consumer); dependencies.media_info_repo->register_extractor([](const std::wstring& file, const std::wstring& extension, core::media_info& info) { - if (extension == L".TGA" - || extension == L".COL" - || extension == L".PNG" - || extension == L".JPEG" - || extension == L".JPG" - || extension == L".GIF" - || extension == L".BMP") + if (supported_extensions().find(boost::to_lower_copy(extension)) != supported_extensions().end()) { info.clip_type = L"STILL"; diff --git a/modules/image/producer/image_producer.cpp b/modules/image/producer/image_producer.cpp index b1857407b..6e45f9434 100644 --- a/modules/image/producer/image_producer.cpp +++ b/modules/image/producer/image_producer.cpp @@ -58,7 +58,7 @@ std::pair load_image( { auto bitmap = load_image(filename); FreeImage_FlipVertical(bitmap.get()); - + core::pixel_format_desc desc = core::pixel_format::bgra; auto width = FreeImage_GetWidth(bitmap.get()); auto height = FreeImage_GetHeight(bitmap.get()); @@ -69,21 +69,21 @@ std::pair load_image( FreeImage_GetBits(bitmap.get()), frame.image_data(0).size(), frame.image_data(0).begin()); - + return std::make_pair( core::draw_frame(std::move(frame)), core::constraints(width, height)); } struct image_producer : public core::frame_producer_base -{ +{ core::monitor::subject monitor_subject_; const std::wstring description_; const spl::shared_ptr frame_factory_; const uint32_t length_; core::draw_frame frame_ = core::draw_frame::empty(); core::constraints constraints_; - + image_producer(const spl::shared_ptr& frame_factory, const std::wstring& description, bool thumbnail_mode, uint32_t length) : description_(description) , frame_factory_(frame_factory) @@ -119,13 +119,13 @@ struct image_producer : public core::frame_producer_base 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, core::audio_channel_layout::invalid()); - + std::copy_n(FreeImage_GetBits(bitmap.get()), frame.image_data().size(), frame.image_data().begin()); frame_ = core::draw_frame(std::move(frame)); constraints_.width.set(FreeImage_GetWidth(bitmap.get())); constraints_.height.set(FreeImage_GetHeight(bitmap.get())); } - + // frame_producer core::draw_frame receive_impl() override @@ -144,7 +144,7 @@ struct image_producer : public core::frame_producer_base { return constraints_; } - + std::wstring print() const override { return L"image_producer[" + description_ + L"]"; @@ -163,7 +163,7 @@ struct image_producer : public core::frame_producer_base return info; } - core::monitor::subject& monitor_output() + core::monitor::subject& monitor_output() { return monitor_subject_; } @@ -202,21 +202,6 @@ void describe_producer(core::help_sink& sink, const core::help_repository& repo) L">> LOADBG 1-10 EMPTY MIX 20 AUTO\n", L"Plays a slide show of 3 images for 100 frames each and fades to black."); } -static const auto g_extensions = { - L".png", - L".tga", - L".bmp", - L".jpg", - L".jpeg", - L".gif", - L".tiff", - L".tif", - L".jp2", - L".jpx", - L".j2k", - L".j2c" -}; - spl::shared_ptr create_producer(const core::frame_producer_dependencies& dependencies, const std::vector& params) { auto length = get_param(L"LENGTH", params, std::numeric_limits::max()); @@ -240,7 +225,7 @@ spl::shared_ptr create_producer(const core::frame_producer auto extension = it->path().extension().wstring(); - if (std::find_if(g_extensions.begin(), g_extensions.end(), ieq(extension)) == g_extensions.end()) + if (std::find_if(supported_extensions().begin(), supported_extensions().end(), ieq(extension)) == supported_extensions().end()) continue; files.insert(it->path().wstring()); @@ -281,14 +266,14 @@ spl::shared_ptr create_producer(const core::frame_producer std::wstring filename = env::media_folder() + params.at(0); - auto ext = std::find_if(g_extensions.begin(), g_extensions.end(), [&](const std::wstring& ex) -> bool + auto ext = std::find_if(supported_extensions().begin(), supported_extensions().end(), [&](const std::wstring& ex) -> bool { auto file = caspar::find_case_insensitive(boost::filesystem::path(filename).wstring() + ex); return static_cast(file); }); - if(ext == g_extensions.end()) + if(ext == supported_extensions().end()) return core::frame_producer::empty(); return spl::make_shared(dependencies.frame_factory, *caspar::find_case_insensitive(filename + *ext), false, length); @@ -299,14 +284,14 @@ core::draw_frame create_thumbnail(const core::frame_producer_dependencies& depen { std::wstring filename = env::media_folder() + media_file; - auto ext = std::find_if(g_extensions.begin(), g_extensions.end(), [&](const std::wstring& ex) -> bool + auto ext = std::find_if(supported_extensions().begin(), supported_extensions().end(), [&](const std::wstring& ex) -> bool { auto file = caspar::find_case_insensitive(boost::filesystem::path(filename).wstring() + ex); return static_cast(file); }); - if (ext == g_extensions.end()) + if (ext == supported_extensions().end()) return core::draw_frame::empty(); spl::shared_ptr producer = spl::make_shared( @@ -314,7 +299,7 @@ core::draw_frame create_thumbnail(const core::frame_producer_dependencies& depen *caspar::find_case_insensitive(filename + *ext), true, 1); - + return producer->receive(); } diff --git a/modules/image/producer/image_scroll_producer.cpp b/modules/image/producer/image_scroll_producer.cpp index 6bef3da8e..25f598931 100644 --- a/modules/image/producer/image_scroll_producer.cpp +++ b/modules/image/producer/image_scroll_producer.cpp @@ -59,7 +59,7 @@ #include namespace caspar { namespace image { - + // Like tweened_transform but for speed class speed_tweener { @@ -105,9 +105,9 @@ public: return fetch(); } }; - + struct image_scroll_producer : public core::frame_producer_base -{ +{ core::monitor::subject monitor_subject_; const std::wstring filename_; @@ -124,7 +124,7 @@ struct image_scroll_producer : public core::frame_producer_base int start_offset_x_ = 0; int start_offset_y_ = 0; bool progressive_; - + explicit image_scroll_producer( const spl::shared_ptr& frame_factory, const core::video_format_desc& format_desc, @@ -219,13 +219,13 @@ struct image_scroll_producer : public core::frame_producer_base auto frame = frame_factory->create_frame(this, desc, core::audio_channel_layout::invalid()); if(count >= frame.image_data(0).size()) - { + { std::copy_n(bytes + count - frame.image_data(0).size(), frame.image_data(0).size(), frame.image_data(0).begin()); count -= static_cast(frame.image_data(0).size()); } else { - memset(frame.image_data(0).begin(), 0, frame.image_data(0).size()); + memset(frame.image_data(0).begin(), 0, frame.image_data(0).size()); std::copy_n(bytes, count, frame.image_data(0).begin() + format_desc_.size - count); count = 0; } @@ -247,23 +247,23 @@ struct image_scroll_producer : public core::frame_producer_base desc.planes.push_back(core::pixel_format_desc::plane(format_desc_.width, height_, 4)); auto frame = frame_factory->create_frame(this, desc, core::audio_channel_layout::invalid()); if(count >= frame.image_data(0).size()) - { + { for(int y = 0; y < height_; ++y) std::copy_n(bytes + i * format_desc_.width*4 + y * width_*4, format_desc_.width*4, frame.image_data(0).begin() + y * format_desc_.width*4); - + ++i; count -= static_cast(frame.image_data(0).size()); } else { - memset(frame.image_data(0).begin(), 0, frame.image_data(0).size()); + memset(frame.image_data(0).begin(), 0, frame.image_data(0).size()); auto width2 = width_ % format_desc_.width; for(int y = 0; y < height_; ++y) std::copy_n(bytes + i * format_desc_.width*4 + y * width_*4, width2*4, frame.image_data(0).begin() + y * format_desc_.width*4); count = 0; } - + frames_.push_back(core::draw_frame(std::move(frame))); } @@ -348,13 +348,13 @@ struct image_scroll_producer : public core::frame_producer_base return std::move(result); } - + // frame_producer core::draw_frame render_frame(bool allow_eof) { if(frames_.empty()) return core::draw_frame::empty(); - + core::draw_frame result(get_visible()); auto& fill_translation = result.transform().image_transform.fill_translation; @@ -363,7 +363,7 @@ struct image_scroll_producer : public core::frame_producer_base if (static_cast(std::abs(delta_)) >= height_ + format_desc_.height && allow_eof) return core::draw_frame::empty(); - fill_translation[1] = + fill_translation[1] = static_cast(start_offset_y_) / static_cast(format_desc_.height) + delta_ / static_cast(format_desc_.height); } @@ -372,7 +372,7 @@ struct image_scroll_producer : public core::frame_producer_base if (static_cast(std::abs(delta_)) >= width_ + format_desc_.width && allow_eof) return core::draw_frame::empty(); - fill_translation[0] = + fill_translation[0] = static_cast(start_offset_x_) / static_cast(format_desc_.width) + (delta_) / static_cast(format_desc_.width); } @@ -437,9 +437,9 @@ struct image_scroll_producer : public core::frame_producer_base result = core::draw_frame::interlace(field1, field2, format_desc_.field_mode); } - + monitor_subject_ << core::monitor::message("/file/path") % filename_ - << core::monitor::message("/delta") % delta_ + << core::monitor::message("/delta") % delta_ << core::monitor::message("/speed") % speed_.fetch(); return result; @@ -449,7 +449,7 @@ struct image_scroll_producer : public core::frame_producer_base { return constraints_; } - + std::wstring print() const override { return L"image_scroll_producer[" + filename_ + L"]"; @@ -516,32 +516,18 @@ void describe_scroll_producer(core::help_sink& sink, const core::help_repository spl::shared_ptr create_scroll_producer(const core::frame_producer_dependencies& dependencies, const std::vector& params) { - static const auto extensions = { - L".png", - L".tga", - L".bmp", - L".jpg", - L".jpeg", - L".gif", - L".tiff", - L".tif", - L".jp2", - L".jpx", - L".j2k", - L".j2c" - }; std::wstring filename = env::media_folder() + params.at(0); - - auto ext = std::find_if(extensions.begin(), extensions.end(), [&](const std::wstring& ex) -> bool + + auto ext = std::find_if(supported_extensions().begin(), supported_extensions().end(), [&](const std::wstring& ex) -> bool { auto file = caspar::find_case_insensitive(boost::filesystem::path(filename).replace_extension(ex).wstring()); return static_cast(file); }); - if(ext == extensions.end()) + if(ext == supported_extensions().end()) return core::frame_producer::empty(); - + double duration = 0.0; double speed = get_param(L"SPEED", params, 0.0); boost::optional end_time; diff --git a/modules/image/util/image_loader.cpp b/modules/image/util/image_loader.cpp index 1768d2891..6ca2fe6f9 100644 --- a/modules/image/util/image_loader.cpp +++ b/modules/image/util/image_loader.cpp @@ -54,20 +54,20 @@ std::shared_ptr load_image(const std::wstring& filename) fif = FreeImage_GetFIFFromFilename(u8(filename).c_str()); #endif - if(fif == FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif)) + if(fif == FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif)) CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); - + #ifdef WIN32 auto bitmap = std::shared_ptr(FreeImage_LoadU(fif, filename.c_str(), 0), FreeImage_Unload); #else auto bitmap = std::shared_ptr(FreeImage_Load(fif, u8(filename).c_str(), 0), FreeImage_Unload); #endif - + if(FreeImage_GetBPP(bitmap.get()) != 32) { bitmap = std::shared_ptr(FreeImage_ConvertTo32Bits(bitmap.get()), FreeImage_Unload); if(!bitmap) - CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); + CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); } //PNG-images need to be premultiplied with their alpha @@ -76,7 +76,7 @@ std::shared_ptr load_image(const std::wstring& filename) image_view original_view(FreeImage_GetBits(bitmap.get()), FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get())); premultiply(original_view); } - + return bitmap; } @@ -100,4 +100,25 @@ std::shared_ptr load_png_from_memory(const void* memory_location, size return bitmap; } +const std::set& supported_extensions() +{ + static const std::set extensions = + { + L".png", + L".tga", + L".bmp", + L".jpg", + L".jpeg", + L".gif", + L".tiff", + L".tif", + L".jp2", + L".jpx", + L".j2k", + L".j2c" + }; + + return extensions; +} + }} diff --git a/modules/image/util/image_loader.h b/modules/image/util/image_loader.h index ae8bf0cab..3c713bd32 100644 --- a/modules/image/util/image_loader.h +++ b/modules/image/util/image_loader.h @@ -25,10 +25,12 @@ #include #include +#include namespace caspar { namespace image { std::shared_ptr load_image(const std::wstring& filename); std::shared_ptr load_png_from_memory(const void* memory_location, size_t size); +const std::set& supported_extensions(); }}