genericimagedatalocal.h 10.5 KB
Newer Older
1
2
3
4
5
6
7
#ifndef GENERICIMAGEDATALOCAL_H__
#define GENERICIMAGEDATALOCAL_H__

#include "tgt/vector.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/tools/typetraits.h"

8
#include <cstring>  // needed for memcpy
9
10
11

namespace TUMVis {

12
13
14
15
16
17
18
    /**
     * Templated version of ImageDataLocal, storing image data in the local memory.
     *
     * \sa      TypeTraits
     * \tparam  BASETYPE    Base type of the image data (type of a single channel of an image element)
     * \tparam  NUMCHANNELS Number of channels of the image data.
     */
19
20
21
    template<typename BASETYPE, size_t NUMCHANNELS>
    class GenericImageDataLocal : public ImageDataLocal {
    public:
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        /// Type of one single image element
        typedef typename TypeTraits<BASETYPE, NUMCHANNELS>::ElementType ElementType;
        /// Type of this template instantiation
        typedef GenericImageDataLocal<BASETYPE, NUMCHANNELS> ThisType;

        /**
         * Creates a new strongly typed ImageData object storing the image in the local memory.
         * 
         * \param   dimensionality  Dimensionality of data
         * \param   size            Size of this image (number of elements per dimension)
         * \param   data            Pointer to the image data, must not be 0, GenericImageDataLocal takes ownership of this pointer!
         */
        GenericImageDataLocal(size_t dimensionality, const tgt::svec3& size, ElementType* data);

        /**
         * Destructor
         */
39
40
41
42
        virtual ~GenericImageDataLocal();


        /// \see AbstractData::clone()
43
        virtual ThisType* clone() const;
44
45

        /// \see ImageData::getSubImage
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
        virtual ThisType* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;

        /// \see ImageDataLocal::getElementNormalized
        virtual float getElementNormalized(const tgt::svec3& position, size_t channel) const;

        /// \see ImageDataLocal::setElementNormalized
        virtual void setElementNormalized(const tgt::svec3& position, size_t channel, float value);


        /**
         * Returns the image element at the given index \a index.
         * \param   index   Array index of the image element to return.
         * \return  Image element at index \a index.
         */
        ElementType& getElement(size_t index);

        /**
         * Returns the image element at the given position in image space.
         * \param   position    Pixel/voxel coordinates of the image element to return.
         * \return  Image element at the coordinates \a position.
         */
        ElementType& getElement(const tgt::svec3& position);

        /**
         * Returns the image element at the given index \a index.
         * \param   index   Array index of the image element to return.
         * \return  Image element at index \a index.
         */
        const ElementType& getElement(size_t index) const;

        /**
         * Returns the image element at the given position in image space.
         * \param   position    Pixel/voxel coordinates of the image element to return.
         * \return  Image element at the coordinates \a position.
         */
        const ElementType& getElement(const tgt::svec3& position) const;

        /**
         * Sets the image element at the given index to the value \a value.
         * \param   index   Array index of the image element to change.
         * \param   value   New value of the specified image element.
         */
        void setElement(size_t index, const ElementType& value);

        /**
         * Sets the image element at the given position in image space to the value \a value.
         * \param   position    Pixel/voxel coordinates of the image element to change.
         * \param   value       New value of the specified image element.
         */
        void setElement(const tgt::svec3& position, const ElementType& value);

        /**
         * Returns a pointer to the image data.
         * \return  _data
         */
        ElementType* getImageData();

        /**
         * Returns a const pointer to the image data.
         * \return  _data
         */
        const ElementType* getImageData() const;


        /**
         * Returns the image element at the given coordinates \a position using bi-/trilinear filtering.
         * \param   position    Pixel/voxel coordinates of the image element to return.
         * \return  Bi-/Trilinear filtered image element at the specified coordinates.
         */
        ElementType getElementLinear(const tgt::vec3 position) const;

117
118
    protected:

119
        ElementType* _data;
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// = Template implementation ======================================================================

    template<typename BASETYPE, size_t NUMCHANNELS>
    TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::GenericImageDataLocal(size_t dimensionality, const tgt::svec3& size, ElementType* data)
        : ImageDataLocal(dimensionality, size, TypeTraits<BASETYPE, NUMCHANNELS>::weaklyTypedPointerBaseType, NUMCHANNELS)
        , _data(data)
    {
        tgtAssert(data != 0, "Pointer to image data must not be 0!");
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::~GenericImageDataLocal() {
        delete _data;
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    GenericImageDataLocal<BASETYPE, NUMCHANNELS>* TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::clone() const {
        size_t numElements = tgt::hmul(_size);
        ElementType* newData = new ElementType[numElements];
        memcpy(newData, _data, numElements * sizeof(ElementType));

        return new ThisType(_dimensionality, _size, newData);
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    GenericImageDataLocal<BASETYPE, NUMCHANNELS>* TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const {
        tgtAssert(tgt::hand(tgt::lessThan(llf, urb)), "Coordinates in LLF must be component-wise smaller than the ones in URB!");

        tgt::svec3 newSize = urb - llf;
        if (newSize == _size) {
            // nothing has changed, just provide a copy:
            return clone();
        }

        size_t numBytesPerElement = sizeof(ElementType);
        size_t numElements = tgt::hmul(_size);
        ElementType* newData = new ElementType[numElements];

        // slice image data into new array
        size_t index = 0;
        for (size_t z = llf.z; z < urb.z; ++z) {
            for (size_t y = llf.y; y < urb.y; ++y) {
                size_t offset = llf.x + (y * _size.x) + (z * _size.y * _size.x);
                memcpy(newData + index, _data + offset, newSize.x * numBytesPerElement);
                index += newSize.x;
            }
        }        

        return new ThisType(_dimensionality, newSize, newData);
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    float TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElementNormalized(const tgt::svec3& position, size_t channel) const {
        tgtAssert(channel >= 0 && channel < NUMCHANNELS, "Channel out of bounds!");
        return TypeNormalizer::normalizeToFloat(TypeTraits<BASETYPE, NUMCHANNELS>::getChannel(getElement(position), channel));
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    void TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::setElementNormalized(const tgt::svec3& position, size_t channel, float value) {
        tgtAssert(channel >= 0 && channel < NUMCHANNELS, "Channel out of bounds!");
        TypeTraits<BASETYPE, NUMCHANNELS>::setChannel(getElement(position), channel, TypeNormalizer::denormalizeFromFloat<BASETYPE>(value));
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType& TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElement(size_t position) {
        tgtAssert(position >= 0 && position < _numElements, "Position out of bounds!");
        return _data[position];
    }
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    template<typename BASETYPE, size_t NUMCHANNELS>
    typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType& TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElement(const tgt::svec3& position) {
        return getElement(positionToIndex(position));
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    const typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType& TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElement(size_t position) const {
        tgtAssert(position >= 0 && position < _numElements, "Position out of bounds!");
        return _data[position];
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    const typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType& TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElement(const tgt::svec3& position) const {
        return getElement(positionToIndex(position));
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    void TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::setElement(size_t position, const ElementType& value) {
        tgtAssert(position >= 0 && position < _numElements, "Position out of bounds!");
        _data[position] = value;
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    void TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::setElement(const tgt::svec3& position, const ElementType& value) {
        _data[positionToIndex(position)] = value;
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType* TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getImageData() {
        return _data;
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    const typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType* TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getImageData() const {
        return _data;
    }

    template<typename BASETYPE, size_t NUMCHANNELS>
    typename TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::ElementType TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElementLinear(const tgt::vec3 position) const {
        // yet to be implemented
        // TODO: Check wether pixel/voxel coordinates lie on the edges or on the center of the pixels/voxels
        tgtAssert(false, "Yet to be implemented!");
        return ElementType(0);
    }
237
238
239
}

#endif // GENERICIMAGEDATALOCAL_H__