File: ImageLoader.cpp

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (160 lines) | stat: -rw-r--r-- 4,081 bytes parent folder | download | duplicates (3)
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
156
157
158
159
160
#include "ImageLoader.h"
#include "TGALoader.h"
#include "JPEGLoader.h"
#include "BMPLoader.h"
#include "PNGLoader.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()
{
    // PNG Loader
    addLoaderToMap(std::make_shared<PNGLoader>());

    // 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& rawName) const
{
    // Replace backslashes with forward slashes and strip of
    // the file extension of the provided token, and store
    // the result in the provided string.
    auto name  = os::standardPath(rawName).substr(0, rawName.rfind("."));

	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 IApplicationContext&)
{
    // 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::StaticModuleRegistration<ImageLoader> imageLoaderModule;

} // namespace shaders