Developer Documentation
ImageStorage.cc
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43
44#include "ImageStorage.hh"
45
47
48static ImageStore store;
49
50ImageStore& imageStore() {
51 return store;
52}
53
54// ---------------------------------------------------------------------------
55
56ImageStore::ImageStore():
57 nextId_(1)
58{
59}
60
61// ---------------------------------------------------------------------------
62
63int ImageStore::addImageFile( QString _fileName ) {
64
65 // Clean error string
66 errorString_ = "No error";
67
68 QString loadFilename;
69
70 // Construct complete filename
71 // if it starts with "/" or "." or contains a ":" it is a global filename and we don't touch it
72 // otherwise we take a relative path from our texture dir
73 if ( _fileName.startsWith("/") || _fileName.startsWith(".") || _fileName.contains(":") )
74 loadFilename = _fileName;
75 else
76 loadFilename = OpenFlipper::Options::textureDirStr() + QDir::separator() + _fileName;
77
78 // Check if it already exists and return the existing one rather than recreating a new one
79 QMap< QString,QPair<int,QDateTime> >::const_iterator it = filenameMap_.find(loadFilename);
80 QFileInfo fileInfo(loadFilename);
81 if ( it != filenameMap_.end() && it->second == fileInfo.lastModified()) {
82
83 // Get id of the existing image
84 int existingId = filenameMap_[loadFilename].first;
85
86 // Update refcount
87 refCount_[existingId] = refCount_[existingId] + 1;
88
89 // Return existing ones id
90 return existingId;
91 }
92
93 if ( !fileInfo.exists() ) {
94 errorString_ = "addedEmptyObject: Cannot load global texture '"+ loadFilename +"'. File not found!" ;
95 return -1;
96
97 }
98
99 QImage image;
100
101 //QImage cannot handle tga directly
102 if ( fileInfo.suffix().toLower() == "tga" ){
103
104 QPixmap pic(loadFilename);
105 image = pic.toImage();
106
107 } else {
108 //load the image
109 if ( !image.load( loadFilename ) ){
110 errorString_ = "Unable to load Image from file " + loadFilename;
111 return -1;
112 }
113 }
114
115 // Store the mapping from filename to id
116 filenameMap_[loadFilename]= qMakePair(nextId_, fileInfo.lastModified());
117 reverseFilenameMap_[nextId_] = loadFilename;
118
119 // Initialize refcount
120 refCount_[nextId_] = 1;
121
122 // Store image
123 imageMap_[nextId_] = image;
124
125 // Increment for next image
126 nextId_++;
127
128 // return the id of the added one
129 return (nextId_ - 1);
130
131
132}
133
134// ---------------------------------------------------------------------------
135
136int ImageStore::addImage( QImage _image ) {
137
138 // No filename mapping as it does not have a filename
139
140 // Initialize refcount
141 refCount_[nextId_] = 1;
142
143 // Store image
144 imageMap_[nextId_] = _image;
145
146 // Increment for next image
147 nextId_++;
148
149 // return the id of the added one
150 return (nextId_ - 1);
151}
152
153// ---------------------------------------------------------------------------
154
155int ImageStore::getImageID(QString _filename) {
156
157 // Check if it already exists and return the existing one rather than recreating a new one
158 if ( filenameMap_.contains(_filename)) {
159 return filenameMap_[_filename].first;
160 }
161
162 // Clean error string
163 errorString_ = "getImageID failed. No such image :" + _filename;
164
165 return -1;
166
167}
168
169// ---------------------------------------------------------------------------
170
171QImage& ImageStore::getImage(int _id, bool* _ok) {
172
173 if ( imageMap_.contains(_id)) {
174 if ( _ok)
175 *_ok = true;
176 return imageMap_[_id];
177 } else {
178 if ( _ok)
179 *_ok = false;
180 errorString_ = "getImage: Unknown image id : " + QString::number(_id);
181 return dummy_;
182 }
183}
184
185// ---------------------------------------------------------------------------
186
187void ImageStore::removeImage(int _id) {
188
189 // Check if it exists
190 if ( refCount_.contains(_id)) {
191 if ( refCount_[_id] > 1 ) {
192 refCount_[_id] = refCount_[_id] - 1;
193 return;
194 } else {
195
196 // Remove from refCount
197 refCount_.remove(_id);
198 imageMap_.remove(_id);
199
200 // This image is from a file and not directly added
201 if ( reverseFilenameMap_.contains(_id)) {
202
203 // Get the filename
204 QString fileName = reverseFilenameMap_[_id];
205
206 reverseFilenameMap_.remove(_id);
207 filenameMap_.remove(fileName);
208
209 }
210
211 }
212 }
213}
214
215
216
217
218
219
220
221
222
223
224
225
226
227