/
ImageLoader.cpp
155 lines (123 loc) · 3.79 KB
/
ImageLoader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "ImageLoader.h"
#include "ImageLoaderWx.h"
#include "TGALoader.h"
#include "JPEGLoader.h"
#include "BMPLoader.h"
#include "dds.h"
#include "ifilesystem.h"
#include "iarchive.h"
#include "iregistry.h"
#include "igame.h"
#include "string/case_conv.h"
#include "os/path.h"
#include "DirectoryArchiveFile.h"
#include "module/StaticModule.h"
namespace image
{
namespace
{
// Registry key holding texture types
const char* const GKEY_IMAGE_TYPES = "/filetypes/texture//extension";
}
void ImageLoader::addLoaderToMap(const ImageTypeLoader::Ptr& loader)
{
auto extensions = loader->getExtensions();
for (const auto& extension : extensions)
{
_loadersByExtension.emplace(string::to_lower_copy(extension), loader);
}
}
ImageLoader::ImageLoader()
{
// Wx loader (this handles regular image file types like PNG)
addLoaderToMap(std::make_shared<ImageLoaderWx>());
// BMP handler
addLoaderToMap(std::make_shared<BMPLoader>());
// JPEG handler
addLoaderToMap(std::make_shared<JPEGLoader>());
// RLE-supporting TGA loader
addLoaderToMap(std::make_shared<TGALoader>());
// DDS loader
addLoaderToMap(std::make_shared<DDSLoader>());
}
// Load image from VFS
ImagePtr ImageLoader::imageFromVFS(const std::string& name) const
{
for (const auto& extension : _extensions)
{
// Find the loader for this extension
auto loaderIter = _loadersByExtension.find(extension);
if (loaderIter == _loadersByExtension.end())
{
rWarning() << "Doom3ImageLoader: failed to find loader"
" for extension '" << extension << "'" << std::endl;
continue;
}
ImageTypeLoader& ldr = *loaderIter->second;
// Construct the full name of the image to load, including the
// prefix (e.g. "dds/") and the file extension.
std::string fullName = ldr.getPrefix() + name + "." + extension;
// Try to open the file (will fail if the extension does not fit)
auto file = GlobalFileSystem().openFile(fullName);
// Has the file been loaded?
if (file)
{
// Try to invoke the imageloader with a reference to the
// ArchiveFile
return ldr.load(*file);
}
}
// File not found
return ImagePtr();
}
ImagePtr ImageLoader::imageFromFile(const std::string& filename) const
{
ImagePtr image;
// Construct a DirectoryArchiveFile out of the filename
auto file = std::make_shared<archive::DirectoryArchiveFile>(filename, filename);
if (!file->failed())
{
const std::string ext = string::to_lower_copy(
os::getExtension(filename)
);
auto loaderIter = _loadersByExtension.find(ext);
if (loaderIter != _loadersByExtension.end())
{
image = loaderIter->second->load(*file);
}
else
{
rWarning() << "Doom3ImageLoader: no loader found for image "
<< filename << std::endl;
}
}
return image;
}
const std::string& ImageLoader::getName() const
{
static std::string _name(MODULE_IMAGELOADER);
return _name;
}
const StringSet& ImageLoader::getDependencies() const
{
static StringSet _dependencies;
if (_dependencies.empty())
{
_dependencies.insert(MODULE_GAMEMANAGER);
}
return _dependencies;
}
void ImageLoader::initialiseModule(const ApplicationContext&)
{
// Load the texture types from the .game file
auto texTypes = GlobalGameManager().currentGame()->getLocalXPath(GKEY_IMAGE_TYPES);
for (const auto& node : texTypes)
{
// Get the file extension, store it as lowercase
std::string extension = node.getContent();
_extensions.emplace_back(string::to_lower_copy(extension));
}
}
// Static module instance
module::StaticModule<ImageLoader> imageLoaderModule;
} // namespace shaders