add image_reader abstraction layer to hanfle multiple image formats

(work-in-progress)
This commit is contained in:
artemp
2014-11-07 11:49:31 +00:00
committed by Leith Bade
parent 90480ee58c
commit ae2d4e740e
9 changed files with 884 additions and 113 deletions

View File

@@ -0,0 +1,50 @@
#ifndef MBGL_UTIL_FACTORY_HPP
#define MBGL_UTIL_FACTORY_HPP
#include "singleton.hpp"
// stl
#include <stdexcept>
#include <map>
namespace mbgl { namespace util {
template
<
typename product_type,
typename key_type,
typename ...Args >
class factory : public singleton<factory <product_type,
key_type,
Args...> >
{
private:
using product_creator = product_type* (*) (Args...);
using product_map = std::map<key_type,product_creator>;
product_map map_;
public:
bool register_product(key_type const& key, product_creator creator)
{
return map_.insert(typename product_map::value_type(key,creator)).second;
}
bool unregister_product(const key_type& key)
{
return map_.erase(key)==1;
}
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;
}
};
}}
#endif

View File

@@ -0,0 +1,50 @@
#ifndef MBGL_UTIL_IMAGE_READER_HPP
#define MBGL_UTIL_IMAGE_READER_HPP
#include "factory.hpp"
#include "noncopyable.hpp"
// stl
#include <stdexcept>
#include <string>
namespace mbgl { namespace util {
class image_reader_exception : public std::exception
{
private:
std::string message_;
public:
image_reader_exception(std::string const& message)
: message_(message) {}
~image_reader_exception() throw() {}
virtual const char* what() const throw()
{
return message_.c_str();
}
};
struct image_reader : private noncopyable
{
virtual unsigned width() const=0;
virtual unsigned height() const=0;
virtual bool has_alpha() const=0;
virtual bool premultiplied_alpha() const=0;
virtual void read(unsigned x,unsigned y, unsigned width, unsigned height, char* image)=0;
virtual ~image_reader() {}
};
template <typename...Args>
bool register_image_reader(std::string const& type, image_reader* (* fun)(Args...))
{
return factory<image_reader,std::string, Args...>::instance().register_product(type, fun);
}
//image_reader* get_image_reader(std::string const& file,std::string const& type);
//image_reader* get_image_reader(std::string const& file);
image_reader* get_image_reader(char const* data, size_t size);
}}
#endif

View File

@@ -0,0 +1,126 @@
#ifndef MBGL_UTIL_SINGLETON_HPP
#define MBGL_UTIL_SINGLETON_HPP
// stl
#include <stdexcept> // std::runtime_error
#include <cstdlib> // std::atexit
#include <new> // operator new
#define SINGLETON_THREADSAFE
#ifdef SINGLETON_THREADSAFE
#include <mutex>
#endif
namespace mbgl { namespace util {
template <typename T>
class CreateUsingNew
{
public:
static T* create()
{
return new T;
}
static void destroy(T* obj)
{
delete obj;
}
};
template <typename T>
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 <typename T,
template <typename U> class CreatePolicy=CreateStatic> class singleton
{
friend class CreatePolicy<T>;
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<T>::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<std::mutex> lock(mutex_);
#endif
if (! pInstance_)
{
if (destroyed_)
{
destroyed_ = false;
onDeadReference();
}
else
{
pInstance_ = CreatePolicy<T>::create();
// register destruction
std::atexit(&DestroySingleton);
}
}
}
return *pInstance_;
}
};
#ifdef SINGLETON_THREADSAFE
template <typename T,
template <typename U> class CreatePolicy> std::mutex singleton<T,CreatePolicy>::mutex_;
#endif
template <typename T,
template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
template <typename T,
template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
}}
#endif //