]> git.sesse.net Git - casparcg/commitdiff
[image_producer] #558 Fixed inconsistency in what file extensions are supported and...
authorHelge Norberg <helge.norberg@svt.se>
Wed, 15 Mar 2017 18:56:08 +0000 (19:56 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Wed, 15 Mar 2017 18:56:08 +0000 (19:56 +0100)
modules/image/image.cpp
modules/image/producer/image_producer.cpp
modules/image/producer/image_scroll_producer.cpp
modules/image/util/image_loader.cpp
modules/image/util/image_loader.h

index a03b01e24a32f952160ddec93e3fe777b238a3a2..2b6eeeef5907d6d5cbaf31dfa7f797f9d1891d75 100644 (file)
@@ -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 <core/producer/frame_producer.h>
 #include <core/consumer/frame_consumer.h>
@@ -35,6 +36,7 @@
 #include <common/utf.h>
 
 #include <boost/property_tree/ptree.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
 
 #include <FreeImage.h>
 
@@ -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";
 
index b1857407b9b726f47ea7e6544224468277ba546d..6e45f9434730cec8acfd0c488848d808104032ea 100644 (file)
@@ -58,7 +58,7 @@ std::pair<core::draw_frame, core::constraints> 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<core::draw_frame, core::constraints> 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<core::frame_factory>      frame_factory_;
        const uint32_t                                                          length_;
        core::draw_frame                                                        frame_                          = core::draw_frame::empty();
        core::constraints                                                       constraints_;
-       
+
        image_producer(const spl::shared_ptr<core::frame_factory>& 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<core::frame_producer> create_producer(const core::frame_producer_dependencies& dependencies, const std::vector<std::wstring>& params)
 {
        auto length = get_param(L"LENGTH", params, std::numeric_limits<uint32_t>::max());
@@ -240,7 +225,7 @@ spl::shared_ptr<core::frame_producer> 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<core::frame_producer> 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<bool>(file);
        });
 
-       if(ext == g_extensions.end())
+       if(ext == supported_extensions().end())
                return core::frame_producer::empty();
 
        return spl::make_shared<image_producer>(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<bool>(file);
        });
 
-       if (ext == g_extensions.end())
+       if (ext == supported_extensions().end())
                return core::draw_frame::empty();
 
        spl::shared_ptr<core::frame_producer> producer = spl::make_shared<image_producer>(
@@ -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();
 }
 
index 6bef3da8ee693c19fadb2507b262e948b0f9f56c..25f59893169e877174604501e7e7e4faab04f3b3 100644 (file)
@@ -59,7 +59,7 @@
 #include <cstdint>
 
 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<core::frame_factory>& 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<int>(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<int>(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<size_t>(std::abs(delta_)) >= height_ + format_desc_.height && allow_eof)
                                return core::draw_frame::empty();
 
-                       fill_translation[1] = 
+                       fill_translation[1] =
                                static_cast<double>(start_offset_y_) / static_cast<double>(format_desc_.height)
                                + delta_ / static_cast<double>(format_desc_.height);
                }
@@ -372,7 +372,7 @@ struct image_scroll_producer : public core::frame_producer_base
                        if (static_cast<size_t>(std::abs(delta_)) >= width_ + format_desc_.width && allow_eof)
                                return core::draw_frame::empty();
 
-                       fill_translation[0] = 
+                       fill_translation[0] =
                                static_cast<double>(start_offset_x_) / static_cast<double>(format_desc_.width)
                                + (delta_) / static_cast<double>(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<core::frame_producer> create_scroll_producer(const core::frame_producer_dependencies& dependencies, const std::vector<std::wstring>& 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<bool>(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<boost::posix_time::ptime> end_time;
index 1768d2891761ae1043e32258adf24fb1517941e8..6ca2fe6f99f6119eea14ebf71d9d9e44297d6bcc 100644 (file)
@@ -54,20 +54,20 @@ std::shared_ptr<FIBITMAP> 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<FIBITMAP>(FreeImage_LoadU(fif, filename.c_str(), 0), FreeImage_Unload);
 #else
        auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_Load(fif, u8(filename).c_str(), 0), FreeImage_Unload);
 #endif
-                 
+
        if(FreeImage_GetBPP(bitmap.get()) != 32)
        {
                bitmap = std::shared_ptr<FIBITMAP>(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<FIBITMAP> load_image(const std::wstring& filename)
                image_view<bgra_pixel> 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<FIBITMAP> load_png_from_memory(const void* memory_location, size
        return bitmap;
 }
 
+const std::set<std::wstring>& supported_extensions()
+{
+       static const std::set<std::wstring> 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;
+}
+
 }}
index ae8bf0cabf8df17563d9dbae2222c12f4a0d90c2..3c713bd32b667b4981e983a514c1814097d04e96 100644 (file)
 
 #include <memory>
 #include <string>
+#include <set>
 
 namespace caspar { namespace image {
 
 std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename);
 std::shared_ptr<FIBITMAP> load_png_from_memory(const void* memory_location, size_t size);
+const std::set<std::wstring>& supported_extensions();
 
 }}