]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/imageloader.cpp
Dirty hack to pull the image loaders in when linking statically
[libs/gui.git] / source / graphics / imageloader.cpp
1 #include <msp/core/refptr.h>
2 #include <msp/io/file.h>
3 #include <msp/strings/format.h>
4 #include "imageloader.h"
5 #ifdef WITH_LIBPNG
6 #include "png/pngloader.h"
7 #endif
8 #ifdef WITH_LIBJPEG
9 #include "jpeg/jpegloader.h"
10 #endif
11 #ifdef WITH_DEVIL
12 #include "devil/devilloader.h"
13 #endif
14 #ifdef WITH_QUARTZ
15 #include "quartz/quartzloader.h"
16 #endif
17
18 using namespace std;
19
20 namespace Msp {
21 namespace Graphics {
22
23 bool ImageLoader::registered_loaders_changed = false;
24
25 ImageLoader::ImageLoader():
26         source(0)
27 { }
28
29 ImageLoader::~ImageLoader()
30 {
31         delete source;
32 }
33
34 ImageLoader *ImageLoader::open_file(const string &fn)
35 {
36         try
37         {
38                 RefPtr<IO::BufferedFile> file = new IO::BufferedFile(fn);
39                 ImageLoader *loader = open_io(*file);
40                 loader->source = file.release();
41                 return loader;
42         }
43         catch(const unsupported_image_format &e)
44         {
45                 throw unsupported_image_format(format("%s: %s", fn, e.what()));
46         }
47 }
48
49 ImageLoader *ImageLoader::open_io(IO::Seekable &io)
50 {
51 #ifdef WITH_LIBPNG
52         (void)RegisteredImageLoader<PngLoader>::reg;
53 #endif
54 #ifdef WITH_LIBJPEG
55         (void)RegisteredImageLoader<JpegLoader>::reg;
56 #endif
57 #ifdef WITH_DEVIL
58         (void)RegisteredImageLoader<DevilLoader>::reg;
59 #endif
60 #ifdef WITH_QUARTZ
61         (void)RegisteredImageLoader<QuartzLoader>::reg;
62 #endif
63
64         list<RegisterBase *> &loaders = get_registered_loaders();
65         if(registered_loaders_changed)
66         {
67                 registered_loaders_changed = false;
68                 loaders.sort(signature_size_compare);
69         }
70
71         if(loaders.empty())
72                 throw unsupported_image_format("no loaders");
73
74         vector<char> sig_buf(loaders.back()->get_signature_size());
75         unsigned sig_len = io.read(&sig_buf[0], sig_buf.size());
76         string signature(sig_buf.begin(), sig_buf.end());
77
78         ImageLoader *loader = 0;
79         for(list<RegisterBase *>::const_iterator i=loaders.begin(); (!loader && i!=loaders.end()); ++i)
80                 if((*i)->detect(signature))
81                         loader = (*i)->create(io);
82
83         io.seek(0, IO::S_BEG);
84
85         if(!loader)
86         {
87                 string sig_hex;
88                 for(unsigned i=0; i<sig_len; ++i)
89                 {
90                         if(i)
91                                 sig_hex += ' ';
92                         sig_hex += format("%02X", static_cast<unsigned char>(sig_buf[i]));
93                 }
94                 throw unsupported_image_format(sig_hex);
95         }
96
97         return loader;
98 }
99
100
101 ImageLoader::RegisterBase::RegisterBase()
102 {
103         get_registered_loaders().push_back(this);
104         registered_loaders_changed = true;
105 }
106
107
108 list<ImageLoader::RegisterBase *> &ImageLoader::get_registered_loaders()
109 {
110         static list<RegisterBase *> regs;
111         return regs;
112 }
113
114 bool ImageLoader::signature_size_compare(RegisterBase *r1, RegisterBase *r2)
115 {
116         return r1->get_signature_size()<r2->get_signature_size();
117 }
118
119 } // namespace Graphics
120 } // namespace Msp