From 759a5e65cf853d679650339e26fef25141ab1901 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 19 Nov 2014 13:06:47 +0100 Subject: [PATCH] simplify image_readers creation implementation * remove static callbacks registration * link png_reader/jpeg_reader into mbgl-linux lib --- gyp/mbgl-linux.gypi | 3 + include/mbgl/util/factory.hpp | 55 ------------- include/mbgl/util/image_reader.hpp | 7 -- include/mbgl/util/jpeg_reader.hpp | 69 ++++++++++++++++ include/mbgl/util/png_reader.hpp | 62 ++++++++++++++ include/mbgl/util/singleton.hpp | 126 ----------------------------- linux/mapboxgl-app.gyp | 2 - platform/default/image_reader.cpp | 16 +++- platform/default/jpeg_reader.cpp | 87 ++------------------ platform/default/png_reader.cpp | 75 +---------------- test/test.gyp | 1 - 11 files changed, 156 insertions(+), 347 deletions(-) delete mode 100644 include/mbgl/util/factory.hpp create mode 100644 include/mbgl/util/jpeg_reader.hpp create mode 100644 include/mbgl/util/png_reader.hpp delete mode 100644 include/mbgl/util/singleton.hpp diff --git a/gyp/mbgl-linux.gypi b/gyp/mbgl-linux.gypi index a66a80ebf..aee928685 100644 --- a/gyp/mbgl-linux.gypi +++ b/gyp/mbgl-linux.gypi @@ -8,6 +8,7 @@ 'variables': { 'cflags_cc': [ '<@(png_cflags)', + '<@(jpeg_cflags)', '<@(uv_cflags)', '<@(curl_cflags)', '<@(nu_cflags)', @@ -32,6 +33,8 @@ '../platform/default/http_request_baton_curl.cpp', '../platform/default/image.cpp', '../platform/default/image_reader.cpp', + '../platform/default/png_reader.cpp', + '../platform/default/jpeg_reader.cpp', ], 'include_dirs': [ '../include', diff --git a/include/mbgl/util/factory.hpp b/include/mbgl/util/factory.hpp deleted file mode 100644 index 1ffcac6f9..000000000 --- a/include/mbgl/util/factory.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef MBGL_UTIL_FACTORY_HPP -#define MBGL_UTIL_FACTORY_HPP - -// stl -#include -#include -#include - -namespace mbgl { namespace util { - -template -< -typename product_type, -typename key_type, -typename ...Args > -class factory -{ -public: - using product_creator = product_type* (*) (Args...); - using product_map = std::map; - static product_map map_; - static std::mutex mutex_; -public: - - static bool register_product(key_type const& key, product_creator creator) - { - std::unique_lock lock(mutex_); - return map_.insert(typename product_map::value_type(key,creator)).second; - } - - static bool unregister_product(const key_type& key) - { - std::unique_lock lock(mutex_); - return map_.erase(key)==1; - } - - static product_type* create_object(key_type const& key, Args...args) - { - typename product_map::const_iterator pos=map_.find(key); - if (pos!=map_.end()) - { - return (pos->second)(args...); - } - return 0; - } -}; - -template -typename factory::product_map factory::map_; -template -typename std::mutex factory::mutex_; - -}} - -#endif diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/util/image_reader.hpp index 144127b76..589653ec5 100644 --- a/include/mbgl/util/image_reader.hpp +++ b/include/mbgl/util/image_reader.hpp @@ -1,7 +1,6 @@ #ifndef MBGL_UTIL_IMAGE_READER_HPP #define MBGL_UTIL_IMAGE_READER_HPP -#include "factory.hpp" #include "noncopyable.hpp" // stl #include @@ -35,12 +34,6 @@ struct image_reader : private noncopyable virtual ~image_reader() {} }; -template -bool register_image_reader(std::string const& type, image_reader* (* fun)(Args...)) -{ - return factory::register_product(type, fun); -} - image_reader* get_image_reader(char const* data, size_t size); }} diff --git a/include/mbgl/util/jpeg_reader.hpp b/include/mbgl/util/jpeg_reader.hpp new file mode 100644 index 000000000..77356007d --- /dev/null +++ b/include/mbgl/util/jpeg_reader.hpp @@ -0,0 +1,69 @@ +#ifndef MBGL_UTIL_JPEG_READER_HPP +#define MBGL_UTIL_JPEG_READER_HPP + +#include "image_reader.hpp" + +// jpeg +extern "C" +{ +#include +} + +#include + +namespace mbgl { namespace util { + +template +class jpeg_reader : public image_reader +{ +public: + using source_type = T; + using input_stream = boost::iostreams::stream; + const static unsigned BUF_SIZE = 4096; +private: + struct jpeg_stream_wrapper + { + jpeg_source_mgr manager; + input_stream * stream; + JOCTET buffer[BUF_SIZE]; + }; + + struct jpeg_info_guard + { + jpeg_info_guard(jpeg_decompress_struct * cinfo) + : i_(cinfo) {} + + ~jpeg_info_guard() + { + jpeg_destroy_decompress(i_); + } + jpeg_decompress_struct * i_; + }; + +private: + source_type source_; + input_stream stream_; + unsigned width_; + unsigned height_; +public: + jpeg_reader(char const* data, size_t size); + ~jpeg_reader(); + unsigned width() const; + unsigned height() const; + inline bool has_alpha() const { return false; } + inline bool premultiplied_alpha() const { return true; } + void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image); +private: + void init(); + static void on_error(j_common_ptr cinfo); + static void on_error_message(j_common_ptr cinfo); + static void init_source(j_decompress_ptr cinfo); + static boolean fill_input_buffer(j_decompress_ptr cinfo); + static void skip(j_decompress_ptr cinfo, long count); + static void term(j_decompress_ptr cinfo); + static void attach_stream(j_decompress_ptr cinfo, input_stream* in); +}; + +}} + +#endif // MBGL_UTIL_JPEG_READER_HPP diff --git a/include/mbgl/util/png_reader.hpp b/include/mbgl/util/png_reader.hpp new file mode 100644 index 000000000..3d6e1db51 --- /dev/null +++ b/include/mbgl/util/png_reader.hpp @@ -0,0 +1,62 @@ +#ifndef MBGL_UTIL_PNG_READER_HPP +#define MBGL_UTIL_PNG_READER_HPP + +#include "mbgl/util/image_reader.hpp" + +extern "C" +{ +#include +} + +#include +#include + +#include + +namespace mbgl { namespace util { + +template +class png_reader : public image_reader +{ + using source_type = T; + using input_stream = boost::iostreams::stream; + + struct png_struct_guard + { + png_struct_guard(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) + : p_(png_ptr_ptr), + i_(info_ptr_ptr) {} + + ~png_struct_guard() + { + png_destroy_read_struct(p_,i_,0); + } + png_structpp p_; + png_infopp i_; + }; + +private: + source_type source_; + input_stream stream_; + unsigned width_; + unsigned height_; + int bit_depth_; + int color_type_; + bool has_alpha_; +public: + png_reader(char const* data, std::size_t size); + ~png_reader(); + unsigned width() const; + unsigned height() const; + inline bool has_alpha() const { return has_alpha_; } + bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html + void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); +private: + void init(); + static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); +}; + + +}} + +#endif // MBGL_UTIL_PNG_READER_HPP diff --git a/include/mbgl/util/singleton.hpp b/include/mbgl/util/singleton.hpp deleted file mode 100644 index a1c1e3ebf..000000000 --- a/include/mbgl/util/singleton.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef MBGL_UTIL_SINGLETON_HPP -#define MBGL_UTIL_SINGLETON_HPP - -// stl -#include // std::runtime_error -#include // std::atexit -#include // operator new -#define SINGLETON_THREADSAFE -#ifdef SINGLETON_THREADSAFE -#include -#endif - -namespace mbgl { namespace util { - -template -class CreateUsingNew -{ -public: - static T* create() - { - return new T; - } - static void destroy(T* obj) - { - delete obj; - } -}; - -template -class CreateStatic -{ -private: - union MaxAlign - { - char t_[sizeof(T)]; - short int shortInt_; - int int_; - long int longInt_; - float float_; - double double_; - long double longDouble_; - struct Test; - int Test::* pMember_; - int (Test::*pMemberFn_)(int); - }; - -public: - - static T* create() - { - static MaxAlign staticMemory; - return new(&staticMemory) T; - } - static void destroy(volatile T* obj) - { - obj->~T(); - } -}; - -template class CreatePolicy=CreateStatic> class singleton -{ - friend class CreatePolicy; - static T* pInstance_; - static bool destroyed_; - singleton(const singleton &rhs); - singleton& operator=(const singleton&); - - static void onDeadReference() - { - throw std::runtime_error("dead reference!"); - } - - static void DestroySingleton() - { - CreatePolicy::destroy(pInstance_); - pInstance_ = 0; - destroyed_ = true; - } - -protected: - -#ifdef SINGLETON_THREADSAFE - static std::mutex mutex_; -#endif - singleton() {} - public: - static T& instance() - { - if (! pInstance_) - { -#ifdef SINGLETON_THREADSAFE - std::unique_lock lock(mutex_); -#endif - if (! pInstance_) - { - if (destroyed_) - { - destroyed_ = false; - onDeadReference(); - } - else - { - pInstance_ = CreatePolicy::create(); - // register destruction - std::atexit(&DestroySingleton); - } - } - } - return *pInstance_; - } -}; - -#ifdef SINGLETON_THREADSAFE - template class CreatePolicy> std::mutex singleton::mutex_; -#endif - - template class CreatePolicy> T* singleton::pInstance_=0; - template class CreatePolicy> bool singleton::destroyed_=false; - -}} - -#endif // diff --git a/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gyp index dbcc4b447..fbeabd74e 100644 --- a/linux/mapboxgl-app.gyp +++ b/linux/mapboxgl-app.gyp @@ -12,8 +12,6 @@ '../platform/default/settings_json.cpp', '../platform/default/glfw_view.cpp', '../platform/default/log_stderr.cpp', - '../platform/default/png_reader.cpp', - '../platform/default/jpeg_reader.cpp', ], 'xcode_settings': { 'OTHER_CPLUSPLUSFLAGS':[ diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 53ab5758a..599ccb13a 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -1,5 +1,9 @@ #include "mbgl/util/image_reader.hpp" +#include "mbgl/util/png_reader.hpp" +#include "mbgl/util/jpeg_reader.hpp" + #include +#include namespace mbgl { namespace util { @@ -43,10 +47,16 @@ image_reader* get_image_reader(char const* data, size_t size) boost::optional type = type_from_bytes(data,size); if (type) { - return factory::create_object(*type, data,size); + if (*type == "png") + { + return new png_reader(data, size); + } + else if (*type == "jpeg") + { + return new jpeg_reader(data, size); + } } - else - throw image_reader_exception("image_reader: can't determine type from input data"); + throw image_reader_exception("image_reader: can't determine type from input data"); } }} diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index f1e9d0fdf..b722c08fa 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -1,15 +1,9 @@ -#include "mbgl/util/image_reader.hpp" - -// jpeg -extern "C" -{ -#include -} +#include "mbgl/util/jpeg_reader.hpp" // boost #include #include -#include + // std #include @@ -17,80 +11,7 @@ extern "C" namespace mbgl { namespace util { -template -class jpeg_reader : public image_reader -{ -public: - using source_type = T; - using input_stream = boost::iostreams::stream; - const static unsigned BUF_SIZE = 4096; -private: - struct jpeg_stream_wrapper - { - jpeg_source_mgr manager; - input_stream * stream; - JOCTET buffer[BUF_SIZE]; - }; - - struct jpeg_info_guard - { - jpeg_info_guard(jpeg_decompress_struct * cinfo) - : i_(cinfo) {} - - ~jpeg_info_guard() - { - jpeg_destroy_decompress(i_); - } - jpeg_decompress_struct * i_; - }; - -private: - source_type source_; - input_stream stream_; - unsigned width_; - unsigned height_; -public: - explicit jpeg_reader(std::string const& file_name); - explicit jpeg_reader(char const* data, size_t size); - ~jpeg_reader(); - unsigned width() const; - unsigned height() const; - inline bool has_alpha() const { return false; } - inline bool premultiplied_alpha() const { return true; } - void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image); -private: - void init(); - static void on_error(j_common_ptr cinfo); - static void on_error_message(j_common_ptr cinfo); - static void init_source(j_decompress_ptr cinfo); - static boolean fill_input_buffer(j_decompress_ptr cinfo); - static void skip(j_decompress_ptr cinfo, long count); - static void term(j_decompress_ptr cinfo); - static void attach_stream(j_decompress_ptr cinfo, input_stream* in); -}; - -namespace -{ -image_reader* create_jpeg_reader(char const* data, size_t size) -{ - return new jpeg_reader(data, size); -} - -const static bool registered = register_image_reader("jpeg",create_jpeg_reader); -} - -// ctors -template -jpeg_reader::jpeg_reader(std::string const& file_name) - : source_(file_name,std::ios_base::in | std::ios_base::binary), - stream_(source_), - width_(0), - height_(0) -{ - if (!stream_) throw image_reader_exception("cannot open image file "+ file_name); - init(); -} - +// ctor template jpeg_reader::jpeg_reader(char const* data, size_t size) : source_(data, size), @@ -277,4 +198,6 @@ void jpeg_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char jpeg_finish_decompress(&cinfo); } +template class jpeg_reader; + }} diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 838344286..4d0abce04 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -1,4 +1,4 @@ -#include "mbgl/util/image_reader.hpp" +#include "mbgl/util/png_reader.hpp" #include extern "C" { @@ -16,61 +16,6 @@ extern "C" namespace mbgl { namespace util { -template -class png_reader : public image_reader -{ - using source_type = T; - using input_stream = boost::iostreams::stream; - - struct png_struct_guard - { - png_struct_guard(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) - : p_(png_ptr_ptr), - i_(info_ptr_ptr) {} - - ~png_struct_guard() - { - png_destroy_read_struct(p_,i_,0); - } - png_structpp p_; - png_infopp i_; - }; - -private: - - source_type source_; - input_stream stream_; - unsigned width_; - unsigned height_; - int bit_depth_; - int color_type_; - bool has_alpha_; -public: - explicit png_reader(std::string const& file_name); - png_reader(char const* data, std::size_t size); - ~png_reader(); - unsigned width() const; - unsigned height() const; - inline bool has_alpha() const { return has_alpha_; } - bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html - void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); -private: - void init(); - static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); -}; - -namespace -{ -image_reader* create_png_reader(char const * data, std::size_t size) -{ - return new png_reader(data, size); -} - -const static bool registered = register_image_reader("png",create_png_reader); - -} - - void user_error_fn(png_structp /*png_ptr*/, png_const_charp error_msg) { throw image_reader_exception(std::string("failed to read invalid png: '") + error_msg + "'"); @@ -94,21 +39,6 @@ void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_ } } -template -png_reader::png_reader(std::string const& file_name) - : source_(file_name,std::ios_base::in | std::ios_base::binary), - stream_(source_), - width_(0), - height_(0), - bit_depth_(0), - color_type_(0), - has_alpha_(false) -{ - if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'"); - if (!stream_) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'"); - init(); -} - template png_reader::png_reader(char const* data, std::size_t size) : source_(data,size), @@ -263,4 +193,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char } png_read_end(png_ptr,0); } + +template class png_reader; + }} diff --git a/test/test.gyp b/test/test.gyp index fecb6ed93..86dbcc08a 100644 --- a/test/test.gyp +++ b/test/test.gyp @@ -163,7 +163,6 @@ 'type': 'executable', 'sources': [ './headless.cpp', - '../platform/default/png_reader.cpp', './fixtures/fixture_log.cpp', ], 'conditions': [