imagedata.h 10.8 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22
23
24
// 
// ================================================================================================

schultezub's avatar
schultezub committed
25
26
#ifndef IMAGEDATA_H__
#define IMAGEDATA_H__
schultezub's avatar
schultezub committed
27

28
#include <tbb/concurrent_vector.h>
29
30
#include <tbb/spin_mutex.h>

31
#include "tgt/logmanager.h"
32
#include "tgt/vector.h"
33
34

#include "core/coreapi.h"
schultezub's avatar
schultezub committed
35
#include "core/datastructures/abstractdata.h"
36
#include "core/datastructures/abstractimagerepresentation.h"
schultezub's avatar
schultezub committed
37
#include "core/datastructures/imagemappinginformation.h"
38
#include "core/datastructures/imagerepresentationconverter.h"
39

40
#include <vector>
schultezub's avatar
schultezub committed
41

schultezub's avatar
schultezub committed
42
namespace campvis {
43

schultezub's avatar
schultezub committed
44
45
    /**
     * Stores basic information about one (semantic) image of arbitrary dimension.
46
     * Different representations (e.g. local memory, OpenGL texture) are
schultezub's avatar
schultezub committed
47
48
     * to be defined by inheritance.
     */
49
    class CAMPVIS_CORE_API ImageData : public AbstractData, public IHasWorldBounds {
50
51
52
    // friend so that it can add itself as representation
    friend class AbstractImageRepresentation;

schultezub's avatar
schultezub committed
53
    public:
54
55
56
57
58
59
        /**
         * Creates a new ImageData instance with the given parameters.
         * \param dimensionality    Dimensionality of this image
         * \param size              Size of this image (number of elements per dimension)
         * \param numChannels       Number of channels per element
         */
60
        explicit ImageData(size_t dimensionality, const tgt::svec3& size, size_t numChannels);
schultezub's avatar
schultezub committed
61

62
        /// Destructor
schultezub's avatar
schultezub committed
63
64
        virtual ~ImageData();

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
        /**
         * Prototype - clone method, some people call this virtual constructor...
         * \note    Deep-copies all contained representations!
         * \return  A copy of this object.
         */
        virtual ImageData* clone() const;

        /**
         * Returns the local memory footprint of the data in bytes.
         * \return  Number of bytes occupied in local memory by the data.
         */
        virtual size_t getLocalMemoryFootprint() const;

        /**
         * Returns the video memory footprint of the data in bytes.
         * \return  Number of bytes occupied in video memory by the data.
         */
        virtual size_t getVideoMemoryFootprint() const;

schultezub's avatar
schultezub committed
84
85
86
87
88
89
90
91
92
93
94
95
        /**
         * Dimensionality of this image.
         * \return _dimensionality
         */
        size_t getDimensionality() const;

        /**
         * Size of this image (number of elements per dimension).
         * \return _size
         */
        const tgt::svec3& getSize() const;

96
97
98
99
100
101
        /**
         * Returns the number of channels per element.
         * \return  _numChannels
         */
        size_t getNumChannels() const;

102
103
104
105
106
107
        /**
         * Returns the number of elements (= tgt::hmul(getSize())).
         * \return  _numElements
         */
        size_t getNumElements() const;

schultezub's avatar
schultezub committed
108
109
110
111
112
113
        /**
         * Mapping information of this image
         * \return _mappingInformation
         */
        const ImageMappingInformation& getMappingInformation() const;

114
115
116
117
118
119
        /**
         * Sets the mapping information for this image to \a imi.
         * \param   imi The new ImageMappingInformation for this image.
         */
        void setMappingInformation(const ImageMappingInformation& imi);

schultezub's avatar
schultezub committed
120
        /**
121
122
         * Returns the image extent in world coordinates.
         * \return  The image extent in world coordinates.
schultezub's avatar
schultezub committed
123
         */
124
        virtual tgt::Bounds getWorldBounds() const;
schultezub's avatar
schultezub committed
125

schultezub's avatar
schultezub committed
126
127
128
129
130
131
132
133
        /**
         * Returns the image extent in world coordinates for the given voxel coordinates.
         * \param   llf     Lower-left-front in voxel coordinates.
         * \param   urb     Upper-right-back in voxel coordinates.
         * \return  The image extent in world coordinates for the given voxel coordinates.
         */
        tgt::Bounds getWorldBounds(const tgt::svec3& llf, const tgt::svec3& urb) const;

134
135
136
137
138
139
140
141
142
        /**
         * Transforms a vector based position to the corresponding array index.
         * \note    Caution, this method might return wrong results for non-continuous storage.
         *          In this case you should provide an appropriate overload.
         * \param   position    Vector based image coordinates
         * \return  Array index when image is stored continuously.
         */
        size_t positionToIndex(const tgt::svec3& position) const;

143
144
145
146
147
148
149
150
        /**
         * Transforms an array index to the corresponding vector based position.
         * \note    Caution, this method might return wrong results for non-continuous storage.
         *          In this case you should provide an appropriate overload.
         * \param   index   Array index when image is stored continuously.
         * \return  Vector based image coordinates.
         */
        tgt::svec3 indexToPosition(size_t index) const;
151
152
153

        /**
         * Returns a representation of this image of type \a T.
154
         * Looks, whether such a representations already exists, if not and \a performConversion is 
155
         * set, the method tries to create it via T::tryConvertFrom(). Returns 0 on failure.
156
157
         * \note    You do \b NOT have ownership of the returned pointer!
         *          The returned pointer is valid as long as this ImageData object exists.
158
         * \note    If \a T is OpenGL related, make sure to call this method from a valid and locked OpenGL context.
159
160
161
         * \param   performConversion   Flag whether to perform representation conversion if necessary.
         * \return  A pointer to a representation of type \a T, you do NOT have ownership, valid as long 
         *          as this ImageData object exists. 0 if no such representation could be created.
162
163
         */
        template<typename T>
164
        const T* getRepresentation(bool performConversion = true) const;
165

166
    protected:
167
168
169
        template<typename T>
        const T* tryPerformConversion() const;

170
171
172
173
174
175
176
177
178
179
180
181
182
183
        /**
         * Adds the given representation to the list of representations.
         * \note    Since this is non-publich method, no sanity checks are performed!
         * \param   representation  representation to add, must not be 0.
         */
        void addRepresentation(const AbstractImageRepresentation* representation);

        /**
         * Sets the initial representation of this ImageData.
         * \note    Removes and deletes all existing representations.
         * \param   representation  Initial representation of this image.
         */
        void setInitialRepresentation(const AbstractImageRepresentation* representation);

184
185
186
        /**
         * Clears all representations from the vector and frees the memory.
         * \note    Make sure to call this method only when nobody else holds pointers to the
187
         *          representations as they will be invalidated. This method is \b not thread-safe!
188
189
190
191
         */
        void clearRepresentations();

        /// List of all representations of this image. Mutable to allow lazy instantiation of new representations.
192
        mutable tbb::concurrent_vector<const AbstractImageRepresentation*> _representations;
193

194
195
196
197
        const size_t _dimensionality;                   ///< Dimensionality of this image
        const tgt::svec3 _size;                         ///< Size of this image (number of elements per dimension)
        const size_t _numChannels;                      ///< Number of channels per element
        const size_t _numElements;                      ///< number of elements (= tgt::hmul(size))
schultezub's avatar
schultezub committed
198
199
        ImageMappingInformation _mappingInformation;    ///< Mapping information of this image

200
201
202
        /// Mutex protecting the representation conversions to ensure that there is only one conversion happening at a time.
        mutable tbb::spin_mutex _conversionMutex;

schultezub's avatar
schultezub committed
203
204
205
        static const std::string loggerCat_;
    };

206
207
208
209

// = Template definition ==========================================================================

    template<typename T>
210
    const T* campvis::ImageData::getRepresentation(bool performConversion) const {
211
        // look, whether we already have a suitable representation
212
        for (tbb::concurrent_vector<const AbstractImageRepresentation*>::const_iterator it = _representations.begin(); it != _representations.end(); ++it) {
213
214
            if (const T* tester = dynamic_cast<const T*>(*it)) {
                return tester;
215
            }
216
217
        }

218
        // no representation found, create a new one
219
        if (performConversion) {
220
221
222
223
224
225
226
227
228
            tbb::spin_mutex::scoped_lock lock(_conversionMutex);

            // in the meantime, there something might have changed, so check again whether there is a new rep.
            for (tbb::concurrent_vector<const AbstractImageRepresentation*>::const_iterator it = _representations.begin(); it != _representations.end(); ++it) {
                if (const T* tester = dynamic_cast<const T*>(*it)) {
                    return tester;
                }
            }

229
230
            return tryPerformConversion<T>();
        }
231

232
233
234
235
236
237
        return 0;
    }

    template<typename T>
    const T* campvis::ImageData::tryPerformConversion() const {
        for (tbb::concurrent_vector<const AbstractImageRepresentation*>::const_iterator it = _representations.begin(); it != _representations.end(); ++it) {
238
            const T* tester = ImageRepresentationConverter::getRef().tryConvertFrom<T>(*it);
239
            if (tester != 0) {
240
                //LDEBUG("Performed a image representation conversion from " + std::string(typeid(**it).name()) + " to " + std::string(typeid(T).name()) + ".");
241
242
                return tester;
            }
243
244
        }

245
        // could not create a suitable representation
246
        LWARNING("Could not create a " + std::string(typeid(T).name()) + " representation.");
247
248
        return 0;
    }
249

schultezub's avatar
schultezub committed
250
251
}

schultezub's avatar
schultezub committed
252
#endif // IMAGEDATA_H__