imagedataram.h 7.28 KB
Newer Older
schultezub's avatar
schultezub committed
1
2
3
4
5
6
7
8
9
#ifndef IMAGEDATARAM_H__
#define IMAGEDATARAM_H__

#include "tgt/vector.h"
#include "core/datastructures/imagedata.h"

#include "core/tools/endianhelper.h"
#include "core/tools/weaklytypedpointer.h"

schultezub's avatar
schultezub committed
10
#include <cstring>
schultezub's avatar
schultezub committed
11
12
13
14
15
16
#include <fstream>
#include <string>

namespace TUMVis {

    /**
schultezub's avatar
schultezub committed
17
     * Templated class storing ImageData in the local memory. Each image element is of type \a T.
schultezub's avatar
schultezub committed
18
     * 
schultezub's avatar
schultezub committed
19
20
21
22
     * \note    Although you can use ImageDataRAM directly (which works perfectly well), it is 
     *          encouraged to use ImageDataRAMTraits for a clearer approach and better support 
     *          of the ImageData converters.
     * \sa      ImageDataRAMTraits
23
     * \todo    implement padding, add some kind of cool iterators
schultezub's avatar
schultezub committed
24
     * \tparam  T   base class of elements
schultezub's avatar
schultezub committed
25
     */
schultezub's avatar
schultezub committed
26
    template<typename T>
schultezub's avatar
schultezub committed
27
28
29
30
31
    class ImageDataRAM : public ImageData {
    public:
        /**
         * Creates a new ImageData disk representation.
         *
schultezub's avatar
schultezub committed
32
         * \note    ImageDataRam takes ownership of \a data.
schultezub's avatar
schultezub committed
33
34
         * \param dimensionality    Dimensionality of data
         * \param size              Size of this image (number of elements per dimension)
schultezub's avatar
schultezub committed
35
         * \param data              Pointer to the image data, must not be 0, ImageDataRAM takes ownership of that pointer.
schultezub's avatar
schultezub committed
36
37
38
39
         */
        ImageDataRAM(
            size_t dimensionality, 
            const tgt::svec3& size,
schultezub's avatar
schultezub committed
40
            T* data = 0
schultezub's avatar
schultezub committed
41
42
43
44
45
46
47
48
49
50
51
            );

        /**
         * Destructor
         */
        virtual ~ImageDataRAM();


        /**
         * \see AbstractData::clone()
         **/
schultezub's avatar
schultezub committed
52
        virtual ImageDataRAM<T>* clone() const;
schultezub's avatar
schultezub committed
53
54
55
56

        /**
         * \see ImageData::getSubImage
         */
schultezub's avatar
schultezub committed
57
        virtual ImageDataRAM<T>* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
schultezub's avatar
schultezub committed
58
59
60
61
62
63


        /**
         * Returns the WeaklyTypedPointer to the image data.
         * \return  Pointer to the image data.
         */
schultezub's avatar
schultezub committed
64
        T* getImageData();
schultezub's avatar
schultezub committed
65
66
67
68
69

        /**
         * Returns the WeaklyTypedPointer to the image data.
         * \return  Pointer to the image data.
         */
schultezub's avatar
schultezub committed
70
        const T* getImageData() const;
schultezub's avatar
schultezub committed
71

schultezub's avatar
schultezub committed
72
    protected:
schultezub's avatar
schultezub committed
73

schultezub's avatar
schultezub committed
74
        T* _data;               ///< pointer to image data
schultezub's avatar
schultezub committed
75
76

        static const std::string loggerCat_;
77
78
79
80
81
82

    private:
        // We don't want this data to be copied - clone() must be enough
        // (read: We are too lazy to implement a correct copy constructor / assignment-operator)
        ImageDataRAM(const ImageDataRAM<T>& rhs) {};
        ImageDataRAM<T>& operator=(const ImageDataRAM& rhs) {};
schultezub's avatar
schultezub committed
83
84
    };

schultezub's avatar
schultezub committed
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
// - Template implementation ----------------------------------------------------------------------

    template<typename T>
    TUMVis::ImageDataRAM<T>::ImageDataRAM(size_t dimensionality, const tgt::svec3& size, T* data) 
        : ImageData(dimensionality, size)
        , _data(data)
    {
    }

    template<typename T>
    TUMVis::ImageDataRAM<T>::~ImageDataRAM() {
        delete _data;
    }

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

        return new ImageDataRAM<T>(_dimensionality, _size, newData);
    }

    template<typename T>
    ImageDataRAM<T>* TUMVis::ImageDataRAM<T>::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(T);
        size_t numElements = tgt::hmul(_size);
        T* newData = new T[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 ImageDataRAM<T>(_dimensionality, newSize, newData);
    }

    template<typename T>
    T* TUMVis::ImageDataRAM<T>::getImageData() {
        return _data;
    }

    template<typename T>
    const T* TUMVis::ImageDataRAM<T>::getImageData() const {
        return _data;
    }

    template<typename T>
    const std::string TUMVis::ImageDataRAM<T>::loggerCat_ = "TUMVis.core.datastructures.ImageDataRAM";

// - Traits and template specializations ----------------------------------------------------------

    /**
     * Collection of traits for ImageDataRAM<T> and its stored image data.
     * Although you can use ImageDataRAM directly (which works perfectly well), it is encouraged
     * to use these traits for a clearer approach and better support of the ImageData converters.
     * \sa      ImageDataRAM
     * \tparam  BASETYPE    Base data type
     * \tparam  NUMCHANNELS Number of channels of each element
     */
    template<typename BASETYPE, size_t NUMCHANNELS>
    struct ImageDataRAMTraits {
160
        //typedef ImageDataRAM<BASETYPE> ImageType;
schultezub's avatar
schultezub committed
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
        
        /**
         * Returns the size of the element base type in bytes.
         */
        static const size_t basetypeSize = sizeof(BASETYPE);

        /**
         * Returns the number of channels per image element.
         */
        static const size_t numChannels = NUMCHANNELS;

        /**
         * Returns the number of bytes required for one image element.
         */
        static const size_t elementSize = sizeof(BASETYPE) * NUMCHANNELS;;
    };


    /**
     * Template specialization of ImageDataRAMTraits with one channel.
     * \sa      ImageDataRAMTraits, ImageDataRAM
     * \tparam  BASETYPE    Base data type
     */
    template<typename BASETYPE>
    struct ImageDataRAMTraits<BASETYPE, 1> {
        typedef ImageDataRAM<BASETYPE> ImageType;
    };

    /**
     * Template specialization of ImageDataRAMTraits with two channels.
     * \sa      ImageDataRAMTraits, ImageDataRAM
     * \tparam  BASETYPE    Base data type
     */
    template<typename BASETYPE>
    struct ImageDataRAMTraits<BASETYPE, 2> {
        typedef ImageDataRAM< tgt::Vector2<BASETYPE> > ImageType;
    };

    /**
     * Template specialization of ImageDataRAMTraits with three channels.
     * \sa      ImageDataRAMTraits, ImageDataRAM
     * \tparam  BASETYPE    Base data type
     */
    template<typename BASETYPE>
    struct ImageDataRAMTraits<BASETYPE, 3> {
        typedef ImageDataRAM< tgt::Vector3<BASETYPE> > ImageType;
    };

    /**
     * Template specialization of ImageDataRAMTraits with four channels.
     * \sa      ImageDataRAMTraits, ImageDataRAM
     * \tparam  BASETYPE    Base data type
     */
    template<typename BASETYPE>
215
    struct ImageDataRAMTraits<BASETYPE, 4> {
schultezub's avatar
schultezub committed
216
217
218
219
220
        typedef ImageDataRAM< tgt::Vector4<BASETYPE> > ImageType;
    };

// - Convenience typedefs -------------------------------------------------------------------------

schultezub's avatar
schultezub committed
221
222
223
}

#endif // IMAGEDATARAM_H__