X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fimageloader.cpp;h=859a34c12894a1a0460b439e230a0fe9154d1385;hb=eddae342dd069589319029b48986b14dbbe5165b;hp=fbba25cd75ae59ce6e194134caea9141e79a2177;hpb=917222bae696465f99024e0e15f73ba1058add44;p=libs%2Fgui.git diff --git a/source/graphics/imageloader.cpp b/source/graphics/imageloader.cpp index fbba25c..859a34c 100644 --- a/source/graphics/imageloader.cpp +++ b/source/graphics/imageloader.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include "bmploader.h" #include "imageloader.h" #ifdef WITH_LIBPNG #include "png/pngloader.h" @@ -20,10 +22,9 @@ using namespace std; namespace Msp { namespace Graphics { -bool ImageLoader::registered_loaders_changed = false; - ImageLoader::ImageLoader(): - source(0) + source(0), + state(INITIAL) { } ImageLoader::~ImageLoader() @@ -31,6 +32,15 @@ ImageLoader::~ImageLoader() delete source; } +bool ImageLoader::detect_signature(const std::string &sig) +{ + Registry ®istry = get_registry(); + for(list::const_iterator i=registry.loaders.begin(); i!=registry.loaders.end(); ++i) + if((*i)->detect(sig)) + return true; + return false; +} + ImageLoader *ImageLoader::open_file(const string &fn) { try @@ -48,35 +58,21 @@ ImageLoader *ImageLoader::open_file(const string &fn) ImageLoader *ImageLoader::open_io(IO::Seekable &io) { -#ifdef WITH_LIBPNG - (void)RegisteredImageLoader::reg; -#endif -#ifdef WITH_LIBJPEG - (void)RegisteredImageLoader::reg; -#endif -#ifdef WITH_DEVIL - (void)RegisteredImageLoader::reg; -#endif -#ifdef WITH_QUARTZ - (void)RegisteredImageLoader::reg; -#endif - - list &loaders = get_registered_loaders(); - if(registered_loaders_changed) + Registry ®istry = get_registry(); + if(registry.changed) { - registered_loaders_changed = false; - loaders.sort(signature_size_compare); + registry.changed = false; + registry.loaders.sort(signature_size_compare); } - if(loaders.empty()) + if(registry.loaders.empty()) throw unsupported_image_format("no loaders"); - vector sig_buf(loaders.back()->get_signature_size()); - unsigned sig_len = io.read(&sig_buf[0], sig_buf.size()); - string signature(sig_buf.begin(), sig_buf.end()); + string signature(registry.loaders.back()->get_signature_size(), 0); + unsigned sig_len = io.read(&signature[0], signature.size()); ImageLoader *loader = 0; - for(list::const_iterator i=loaders.begin(); (!loader && i!=loaders.end()); ++i) + for(list::const_iterator i=registry.loaders.begin(); (!loader && i!=registry.loaders.end()); ++i) if((*i)->detect(signature)) loader = (*i)->create(io); @@ -86,29 +82,57 @@ ImageLoader *ImageLoader::open_io(IO::Seekable &io) { string sig_hex; for(unsigned i=0; i(sig_buf[i])); - } + append(sig_hex, " ", format("%02X", static_cast(signature[i]))); throw unsupported_image_format(sig_hex); } return loader; } - -ImageLoader::RegisterBase::RegisterBase() +void ImageLoader::load(Image::Data &data) { - get_registered_loaders().push_back(this); - registered_loaders_changed = true; + if(state>=FINISHED) + throw logic_error("already loaded"); + + if(state=HEADERS_LOADED) + throw logic_error("headers already loaded"); + + load_headers_(data); + state = HEADERS_LOADED; +} -list &ImageLoader::get_registered_loaders() +ImageLoader::Registry &ImageLoader::get_registry() { - static list regs; - return regs; + static Registry registry; + static bool initialized = false; + if(!initialized) + { + initialized = true; + register_loader(); +#ifdef WITH_LIBPNG + register_loader(); +#endif +#ifdef WITH_LIBJPEG + register_loader(); +#endif +#ifdef WITH_DEVIL + register_loader(); +#endif +#ifdef WITH_QUARTZ + register_loader(); +#endif + } + return registry; } bool ImageLoader::signature_size_compare(RegisterBase *r1, RegisterBase *r2) @@ -116,5 +140,16 @@ bool ImageLoader::signature_size_compare(RegisterBase *r1, RegisterBase *r2) return r1->get_signature_size()get_signature_size(); } + +ImageLoader::Registry::Registry(): + changed(false) +{ } + +ImageLoader::Registry::~Registry() +{ + for(list::iterator i=loaders.begin(); i!=loaders.end(); ++i) + delete *i; +} + } // namespace Graphics } // namespace Msp