Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 97b1566a authored by schultezub's avatar schultezub
Browse files

finished work started on commit #35:

 * Added ImageDataLocal and GenericImageDataLocal<T> replaceing the crapped ImageDataRAM
 * Rewrote most part of TypeTraits and tidied up the rest.
 * Added TypeNormalizer with its traits
 * added ImageData::_numElements and ImageData::positionToIndex()

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@182 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 827ab818
...@@ -11,7 +11,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0 FATAL_ERROR) ...@@ -11,7 +11,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0 FATAL_ERROR)
# #
OPTION(TUMVIS_SHARED_LIBS "Build shared libraries?" ON ) OPTION(TUMVIS_SHARED_LIBS "Build shared libraries?" ON )
OPTION(TUMVIS_PRECOMPILED_HEADER "Use pre-compiled headers?" ON ) #OPTION(TUMVIS_PRECOMPILED_HEADER "Use pre-compiled headers?" ON )
OPTION(TUMVIS_DEBUG "Activate debug code?" ON ) OPTION(TUMVIS_DEBUG "Activate debug code?" ON )
OPTION(TUMVIS_BUILD_APPLICATION "Build TUMVis Application" ON ) OPTION(TUMVIS_BUILD_APPLICATION "Build TUMVis Application" ON )
OPTION(TUMVIS_BUILD_CORE "Build TUMVis Core" ON ) OPTION(TUMVIS_BUILD_CORE "Build TUMVis Core" ON )
...@@ -21,7 +21,7 @@ OPTION(TUMVIS_BUILD_LIB_TGT "Build TGT Library" ...@@ -21,7 +21,7 @@ OPTION(TUMVIS_BUILD_LIB_TGT "Build TGT Library"
IF(WIN32) IF(WIN32)
OPTION(TUMVIS_COPY_EXTERNAL_DLLS "Copy external DLLs to bin directory?" ON ) OPTION(TUMVIS_COPY_EXTERNAL_DLLS "Copy external DLLs to bin directory?" ON )
OPTION(TUMVIS_INCREMENTAL_LINKING "Enable incremental linking in Visual Studio debug builds?" ON ) OPTION(TUMVIS_INCREMENTAL_LINKING "Enable incremental linking in Visual Studio debug builds?" ON )
OPTION(TUMVIS_GENERATE_MANIFEST "Generate manifest in Visual Studio debug builds?" OFF) OPTION(TUMVIS_GENERATE_MANIFEST "Generate manifest in Visual Studio debug builds (switch on when encountering errors using incremental linking)?" OFF)
ENDIF() ENDIF()
# #
......
...@@ -3,40 +3,237 @@ ...@@ -3,40 +3,237 @@
#include "tgt/vector.h" #include "tgt/vector.h"
#include "core/datastructures/imagedatalocal.h" #include "core/datastructures/imagedatalocal.h"
#include "core/tools/endianhelper.h"
#include "core/tools/typetraits.h" #include "core/tools/typetraits.h"
#include "core/tools/weaklytypedpointer.h"
#include <cstring> #include <cstring> // needed for memcpy
#include <fstream>
#include <string>
namespace TUMVis { namespace TUMVis {
/**
* 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.
*/
template<typename BASETYPE, size_t NUMCHANNELS> template<typename BASETYPE, size_t NUMCHANNELS>
class GenericImageDataLocal : public ImageDataLocal { class GenericImageDataLocal : public ImageDataLocal {
public: public:
typedef typedef TypeTraits< /// Type of one single image element
typedef typename TypeTraits<BASETYPE, NUMCHANNELS>::ElementType ElementType;
GenericImageDataLocal(size_t dimensionality, const tgt::svec3& size, T* data); /// 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
*/
virtual ~GenericImageDataLocal(); virtual ~GenericImageDataLocal();
/// \see AbstractData::clone() /// \see AbstractData::clone()
virtual ImageDataLocal<typename BASETYPE, size_t NUMCHANNELS>* clone() const; virtual ThisType* clone() const;
/// \see ImageData::getSubImage /// \see ImageData::getSubImage
virtual ImageDataLocal<typename BASETYPE, size_t NUMCHANNELS>* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const; 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;
protected: protected:
ElementType* _data;
}; };
// - Template implementation ---------------------------------------------------------------------- // = 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];
}
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;
}
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);
}
} }
#endif // GENERICIMAGEDATALOCAL_H__ #endif // GENERICIMAGEDATALOCAL_H__
...@@ -6,6 +6,7 @@ namespace TUMVis { ...@@ -6,6 +6,7 @@ namespace TUMVis {
ImageData::ImageData(size_t dimensionality, const tgt::svec3& size) ImageData::ImageData(size_t dimensionality, const tgt::svec3& size)
: _dimensionality(dimensionality) : _dimensionality(dimensionality)
, _size(size) , _size(size)
, _numElements(tgt::hmul(size))
{ {
} }
...@@ -27,4 +28,12 @@ namespace TUMVis { ...@@ -27,4 +28,12 @@ namespace TUMVis {
ImageMappingInformation& ImageData::getMappingInformation() { ImageMappingInformation& ImageData::getMappingInformation() {
return _mappingInformation; return _mappingInformation;
} }
size_t ImageData::getNumElements() const {
return _numElements;
}
size_t ImageData::positionToIndex(const tgt::svec3& position) const {
return position.x + (position.y * _size.x) + (position.z * _size.x * _size.y);
}
} }
\ No newline at end of file
...@@ -32,6 +32,12 @@ namespace TUMVis { ...@@ -32,6 +32,12 @@ namespace TUMVis {
*/ */
const tgt::svec3& getSize() const; const tgt::svec3& getSize() const;
/**
* Returns the number of elements (= tgt::hmul(getSize())).
* \return _numElements
*/
size_t getNumElements() const;
/** /**
* Mapping information of this image * Mapping information of this image
* \return _mappingInformation * \return _mappingInformation
...@@ -55,8 +61,18 @@ namespace TUMVis { ...@@ -55,8 +61,18 @@ namespace TUMVis {
virtual ImageData* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0; virtual ImageData* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
protected: protected:
/**
* 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;
size_t _dimensionality; ///< Dimensionality of this image size_t _dimensionality; ///< Dimensionality of this image
tgt::svec3 _size; ///< Size of this image (number of elements per dimension) tgt::svec3 _size; ///< Size of this image (number of elements per dimension)
size_t _numElements; ///< number of elements (= tgt::hmul(size))
ImageMappingInformation _mappingInformation; ///< Mapping information of this image ImageMappingInformation _mappingInformation; ///< Mapping information of this image
static const std::string loggerCat_; static const std::string loggerCat_;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "tgt/texture.h" #include "tgt/texture.h"
#include "tgt/vector.h" #include "tgt/vector.h"
#include "core/datastructures/imagedata.h" #include "core/datastructures/imagedata.h"
#include "core/tools/typetraits.h" #include "core/datastructures/genericimagedatalocal.h"
#include "core/tools/weaklytypedpointer.h" #include "core/tools/weaklytypedpointer.h"
namespace TUMVis { namespace TUMVis {
...@@ -25,16 +25,16 @@ namespace TUMVis { ...@@ -25,16 +25,16 @@ namespace TUMVis {
ImageDataGL(size_t dimensionality, const tgt::svec3& size, const WeaklyTypedPointer& wtp); ImageDataGL(size_t dimensionality, const tgt::svec3& size, const WeaklyTypedPointer& wtp);
/** /**
* Creates a new ImageDataGL representation from ImageDataRAM. * Creates a new ImageDataGL representation from GenericImageDataLocal.
* *
* \param dimensionality Dimensionality of data * \param dimensionality Dimensionality of data
* \param size Size of this image (number of elements per dimension) * \param size Size of this image (number of elements per dimension)
* \param data Pointer to the ImageDataRAM instance, must not be 0, type has to match the template parameters. * \param data Pointer to the GenericImageDataLocal instance, must not be 0
* \tparam BASETYPE Base type of image data * \tparam BASETYPE Base type of image data
* \tparam NUMCHANNELS Number of channels per element * \tparam NUMCHANNELS Number of channels per element
*/ */
template<typename BASETYPE, size_t NUMCHANNELS> template<typename BASETYPE, size_t NUMCHANNELS>
ImageDataGL(size_t dimensionality, const tgt::svec3& size, typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* data); ImageDataGL(size_t dimensionality, const tgt::svec3& size, const GenericImageDataLocal<BASETYPE, NUMCHANNELS>* data);
/** /**
* Destructor * Destructor
...@@ -64,12 +64,12 @@ namespace TUMVis { ...@@ -64,12 +64,12 @@ namespace TUMVis {
/** /**
* Creates the OpenGL texture from the given ImageDataRAM \a data. * Creates the OpenGL texture from the given ImageDataRAM \a data.
* \param data Pointer to the ImageDataRAM instance, must not be 0, type has to match the template parameters. * \param data Pointer to the GenericImageDataLocal instance, must not be 0
* \tparam BASETYPE Base type of image data * \tparam BASETYPE Base type of image data
* \tparam NUMCHANNELS Number of channels per element * \tparam NUMCHANNELS Number of channels per element
*/ */
template<typename BASETYPE, size_t NUMCHANNELS> template<typename BASETYPE, size_t NUMCHANNELS>
void createTexture(typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* data); void createTexture(const GenericImageDataLocal<BASETYPE, NUMCHANNELS>* data);
tgt::Texture* _texture; //< OpenGL texture tgt::Texture* _texture; //< OpenGL texture
...@@ -79,14 +79,14 @@ namespace TUMVis { ...@@ -79,14 +79,14 @@ namespace TUMVis {
// = Template definition ========================================================================== // = Template definition ==========================================================================
template<typename BASETYPE, size_t NUMCHANNELS> template<typename BASETYPE, size_t NUMCHANNELS>
TUMVis::ImageDataGL::ImageDataGL(size_t dimensionality, const tgt::svec3& size, typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* imageRAM) TUMVis::ImageDataGL::ImageDataGL(size_t dimensionality, const tgt::svec3& size, const GenericImageDataLocal<BASETYPE, NUMCHANNELS>* data)
: ImageData(dimensionality, size) : ImageData(dimensionality, size)
{ {
createTexture<BASETYPE, NUMCHANNELS>(data); createTexture<BASETYPE, NUMCHANNELS>(data);
} }
template<typename BASETYPE, size_t NUMCHANNELS> template<typename BASETYPE, size_t NUMCHANNELS>
void TUMVis::ImageDataGL::createTexture(typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* data) { void TUMVis::ImageDataGL::createTexture(const GenericImageDataLocal<BASETYPE, NUMCHANNELS>* data) {
tgtAssert(data != 0, "Pointer to image must not be 0!"); tgtAssert(data != 0, "Pointer to image must not be 0!");
_texture = new tgt::Texture( _texture = new tgt::Texture(
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
namespace TUMVis { namespace TUMVis {
/** /**
* Abstract base class for strongly typed (templated) ImageDataRAM * Abstract base class for storing image data in the local memory
* *
* \todo implement padding, add some kind of cool iterators * \todo implement padding, add some kind of cool iterators
*/ */
...@@ -44,20 +44,6 @@ namespace TUMVis { ...@@ -44,20 +44,6 @@ namespace TUMVis {
*/ */
virtual ImageDataLocal* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0; virtual ImageDataLocal* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
/**
* Returns the WeaklyTypedPointer to the image data.
* \return Pointer to the image data.
*/
virtual WeaklyTypedPointer& getImageData() = 0;
/**
* Returns the WeaklyTypedPointer to the image data.
* \return Pointer to the image data.
*/
virtual const WeaklyTypedPointer& getImageData() const = 0;
/** /**
* Returns the normalized value of the element at the given position and channel. * Returns the normalized value of the element at the given position and channel.
* - for \em unsigned integer types, the value range is mapped linearly to [0.0;1.0] * - for \em unsigned integer types, the value range is mapped linearly to [0.0;1.0]
......
#include "imagedataram.h"
namespace TUMVis {
/*
const std::string ImageDataRAM::loggerCat_ = "TUMVis.core.datastructures.ImageDataRAM";
ImageDataRAM::ImageDataRAM(size_t dimensionality, const tgt::svec3& size, WeaklyTypedPointer data)
: ImageData(dimensionality, size)
, _data(data)
{
Full<int, 2> f;
f.foo(tgt::ivec2(1, 2));
}
ImageDataRAM::~ImageDataRAM() {
delete _data._pointer;
}
ImageDataRAM* ImageDataRAM::clone() const {
size_t numBytes = tgt::hmul(_size) * _data.numBytes();
char* newData = new char[numBytes];
memcpy(newData, _data._pointer, numBytes);
return new ImageDataRAM(_dimensionality, _size, WeaklyTypedPointer(_data._pointerType, static_cast<void*>(newData)));
}
ImageDataRAM* ImageDataRAM::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 = _data.numBytes();
size_t numBytesTotal = tgt::hmul(newSize) * numBytesPerElement;
char* newData = new char[numBytesTotal];
// 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 * numBytesPerElement), static_cast<char*>(_data._pointer) + (offset * numBytesPerElement), newSize.x * numBytesPerElement);
index += newSize.x;
}
}
return new ImageDataRAM(_dimensionality, newSize, WeaklyTypedPointer(_data._pointerType, static_cast<void*>(newData)));
}
WeaklyTypedPointer& ImageDataRAM::getImageData() {
return _data;
}
const WeaklyTypedPointer& ImageDataRAM::getImageData() const {
return _data;
}*/
}
\ No newline at end of file
#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"
#include <cstring>
#include <fstream>
#include <string>
namespace TUMVis {
/**
* Templated class storing ImageData in the local memory. Each image element is of type \a T.
*
* \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
* \todo implement padding, add some kind of cool iterators
* \tparam T base class of elements
*/
template<typename T>
class ImageDataRAM : public ImageData {
public:
/**
* Creates a new ImageData disk representation.
*