Commit caa7620d authored by schultezub's avatar schultezub
Browse files

=== ATTENTION: CAMPVis does compile, but image representation conversion not...

=== ATTENTION: CAMPVis does compile, but image representation conversion not yet functional again! ===

Revising ImageData concept step 2:
 * Removed all ImageDataXYZ classes
 * Introducing GenericAbstractImageRepresentation<T> and its GenericAbstractImageRepresentation<T>::ScopedRepresentation
 * Updated all processors and pipelines to use ImageRepresentationXYZ instead of ImageDataXYZ and the implicit conversion feature

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@401 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 670e632c
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
// ================================================================================================ // ================================================================================================
#include "application/campvisapplication.h" #include "application/campvisapplication.h"
#include "modules/vis/pipelines/advancedusvis.h"
#include "modules/vis/pipelines/ixpvdemo.h" #include "modules/vis/pipelines/ixpvdemo.h"
#include "modules/vis/pipelines/dvrvis.h" #include "modules/vis/pipelines/dvrvis.h"
#include "modules/vis/pipelines/slicevis.h" #include "modules/vis/pipelines/slicevis.h"
...@@ -44,7 +45,8 @@ using namespace campvis; ...@@ -44,7 +45,8 @@ using namespace campvis;
**/ **/
int main(int argc, char** argv) { int main(int argc, char** argv) {
CampVisApplication app(argc, argv); CampVisApplication app(argc, argv);
app.addVisualizationPipeline("IXPV", new IxpvDemo()); app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis());
//app.addVisualizationPipeline("IXPV", new IxpvDemo());
//app.addVisualizationPipeline("SliceVis", new SliceVis()); //app.addVisualizationPipeline("SliceVis", new SliceVis());
//app.addVisualizationPipeline("DVRVis", new DVRVis()); //app.addVisualizationPipeline("DVRVis", new DVRVis());
//app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline()); //app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline());
......
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
#include "tgt/quadric.h" #include "tgt/quadric.h"
#include "core/datastructures/imagedatarendertarget.h" #include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/pipeline/visualizationpipeline.h" #include "core/pipeline/visualizationpipeline.h"
#include "core/tools/job.h" #include "core/tools/job.h"
#include "core/tools/opengljobprocessor.h" #include "core/tools/opengljobprocessor.h"
...@@ -94,7 +95,7 @@ namespace campvis { ...@@ -94,7 +95,7 @@ namespace campvis {
glViewport(0, 0, size.x, size.y); glViewport(0, 0, size.x, size.y);
// try get Data // try get Data
DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID()); ImageRepresentationRenderTarget::ScopedRepresentation image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (image != 0) { if (image != 0) {
// activate shader // activate shader
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
#include "core/datastructures/datacontainer.h" #include "core/datastructures/datacontainer.h"
#include "core/datastructures/datahandle.h" #include "core/datastructures/datahandle.h"
#include "core/datastructures/imagedatarendertarget.h" #include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/datastructures/imagedatagl.h" #include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/facegeometry.h" #include "core/datastructures/facegeometry.h"
#include "core/tools/job.h" #include "core/tools/job.h"
...@@ -140,10 +140,10 @@ namespace campvis { ...@@ -140,10 +140,10 @@ namespace campvis {
std::vector<const tgt::Texture*> textures; std::vector<const tgt::Texture*> textures;
for (std::map<std::string, DataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) { for (std::map<std::string, DataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
if (const ImageDataGL* imgGL = dynamic_cast<const ImageDataGL*>(it->second.getData())) { if (const ImageRepresentationGL* imgGL = dynamic_cast<const ImageRepresentationGL*>(it->second.getData())) {
textures.push_back(imgGL->getTexture()); textures.push_back(imgGL->getTexture());
} }
else if (const ImageDataRenderTarget* imgRT = dynamic_cast<const ImageDataRenderTarget*>(it->second.getData())) { else if (const ImageRepresentationRenderTarget* imgRT = dynamic_cast<const ImageRepresentationRenderTarget*>(it->second.getData())) {
if (imgRT->getDimensionality() == 2) { if (imgRT->getDimensionality() == 2) {
for (size_t i = 0; i < imgRT->getNumColorTextures(); ++i) for (size_t i = 0; i < imgRT->getNumColorTextures(); ++i)
textures.push_back(imgRT->getColorTexture(i)); textures.push_back(imgRT->getColorTexture(i));
......
...@@ -36,10 +36,10 @@ ...@@ -36,10 +36,10 @@
#include "application/gui/qtdatahandle.h" #include "application/gui/qtdatahandle.h"
#include "core/datastructures/datacontainer.h" #include "core/datastructures/datacontainer.h"
#include "core/datastructures/abstractdata.h" #include "core/datastructures/abstractdata.h"
#include "core/datastructures/imagedatadisk.h" #include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/imagedatalocal.h" #include "core/datastructures/imagerepresentationlocal.h"
#include "core/datastructures/imagedatarendertarget.h" #include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/datastructures/imagedatagl.h" #include "core/datastructures/imagerepresentationgl.h"
#include <QHeaderView> #include <QHeaderView>
#include <QStringList> #include <QStringList>
...@@ -91,16 +91,16 @@ namespace campvis { ...@@ -91,16 +91,16 @@ namespace campvis {
else if (column == COLUMN_TYPE) { else if (column == COLUMN_TYPE) {
const AbstractData* data = _dataHandle.getData(); const AbstractData* data = _dataHandle.getData();
tgtAssert(data != 0, "WTF - QtDataHandle with empty data?"); tgtAssert(data != 0, "WTF - QtDataHandle with empty data?");
if (const ImageDataDisk* tester = dynamic_cast<const ImageDataDisk*>(data)) { if (const ImageRepresentationDisk* tester = dynamic_cast<const ImageRepresentationDisk*>(data)) {
return QVariant(QString("ImageData on disk")); return QVariant(QString("ImageData on disk"));
} }
else if (const ImageDataLocal* tester = dynamic_cast<const ImageDataLocal*>(data)) { else if (const ImageRepresentationLocal* tester = dynamic_cast<const ImageRepresentationLocal*>(data)) {
return QVariant(QString("ImageData in local memory")); return QVariant(QString("ImageData in local memory"));
} }
else if (const ImageDataGL* tester = dynamic_cast<const ImageDataGL*>(data)) { else if (const ImageRepresentationGL* tester = dynamic_cast<const ImageRepresentationGL*>(data)) {
return QVariant(QString("ImageData in OpenGL texture.")); return QVariant(QString("ImageData in OpenGL texture."));
} }
else if (const ImageDataRenderTarget* tester = dynamic_cast<const ImageDataRenderTarget*>(data)) { else if (const ImageRepresentationRenderTarget* tester = dynamic_cast<const ImageRepresentationRenderTarget*>(data)) {
return QVariant(QString("RenderTarget")); return QVariant(QString("RenderTarget"));
} }
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "core/classification/geometry1dtransferfunction.h" #include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h" #include "core/classification/tfgeometry1d.h"
#include "core/datastructures/imagedatalocal.h" #include "core/datastructures/imagerepresentationlocal.h"
#include "core/properties/transferfunctionproperty.h" #include "core/properties/transferfunctionproperty.h"
#include "core/tools/opengljobprocessor.h" #include "core/tools/opengljobprocessor.h"
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "core/classification/geometry2dtransferfunction.h" #include "core/classification/geometry2dtransferfunction.h"
#include "core/classification/TFGeometry2D.h" #include "core/classification/TFGeometry2D.h"
#include "core/datastructures/imagedatalocal.h" #include "core/datastructures/imagerepresentationlocal.h"
#include "core/properties/transferfunctionproperty.h" #include "core/properties/transferfunctionproperty.h"
#include "core/tools/opengljobprocessor.h" #include "core/tools/opengljobprocessor.h"
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "application/gui/properties/abstracttransferfunctioneditor.h" #include "application/gui/properties/abstracttransferfunctioneditor.h"
#include "application/gui/properties/transferfunctioneditorfactory.h" #include "application/gui/properties/transferfunctioneditorfactory.h"
#include "core/datastructures/imagedatalocal.h" #include "core/datastructures/imagerepresentationlocal.h"
#include <QDockWidget> #include <QDockWidget>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
...@@ -97,7 +97,7 @@ namespace campvis { ...@@ -97,7 +97,7 @@ namespace campvis {
void TransferFunctionPropertyWidget::onTransferFunctionImageHandleChanged() { void TransferFunctionPropertyWidget::onTransferFunctionImageHandleChanged() {
DataHandle dh = static_cast<TransferFunctionProperty*>(_property)->getTF()->getImageHandle(); DataHandle dh = static_cast<TransferFunctionProperty*>(_property)->getTF()->getImageHandle();
if (dh.getData() != 0) { if (dh.getData() != 0) {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(dh.getData()); const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(dh.getData());
if (idl != 0) { if (idl != 0) {
Interval<float> intensityInterval = idl->getNormalizedIntensityRange(); Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
// _spinDomainLeft->setMinimum(intensityInterval.getLeft()); // _spinDomainLeft->setMinimum(intensityInterval.getLeft());
...@@ -150,7 +150,7 @@ namespace campvis { ...@@ -150,7 +150,7 @@ namespace campvis {
DataHandle dh = tf->getImageHandle(); DataHandle dh = tf->getImageHandle();
if (dh.getData() != 0) { if (dh.getData() != 0) {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(dh.getData()); const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(dh.getData());
if (idl != 0) { if (idl != 0) {
Interval<float> intensityInterval = idl->getNormalizedIntensityRange(); Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
tf->setIntensityDomain(tgt::vec2(intensityInterval.getLeft(), intensityInterval.getRight())); tf->setIntensityDomain(tgt::vec2(intensityInterval.getLeft(), intensityInterval.getRight()));
......
...@@ -36,13 +36,13 @@ ...@@ -36,13 +36,13 @@
#include "tgt/texture.h" #include "tgt/texture.h"
#include "tgt/textureunit.h" #include "tgt/textureunit.h"
#include "core/datastructures/imagedatalocal.h" #include "core/datastructures/imagerepresentationlocal.h"
namespace campvis { namespace campvis {
class IntensityHistogramGenerator { class IntensityHistogramGenerator {
public: public:
IntensityHistogramGenerator(const ImageDataLocal* intensityData, AbstractTransferFunction::IntensityHistogramType* histogram) IntensityHistogramGenerator(const ImageRepresentationLocal* intensityData, AbstractTransferFunction::IntensityHistogramType* histogram)
: _intensityData(intensityData) : _intensityData(intensityData)
, _histogram(histogram) , _histogram(histogram)
{} {}
...@@ -55,7 +55,7 @@ namespace campvis { ...@@ -55,7 +55,7 @@ namespace campvis {
} }
protected: protected:
const ImageDataLocal* _intensityData; const ImageRepresentationLocal* _intensityData;
AbstractTransferFunction::IntensityHistogramType* _histogram; AbstractTransferFunction::IntensityHistogramType* _histogram;
}; };
...@@ -169,7 +169,7 @@ namespace campvis { ...@@ -169,7 +169,7 @@ namespace campvis {
_intensityHistogram = 0; _intensityHistogram = 0;
if (_imageHandle.getData() != 0) { if (_imageHandle.getData() != 0) {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(_imageHandle.getData()); const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(_imageHandle.getData());
if (idl != 0) { if (idl != 0) {
float mins = _intensityDomain.x; float mins = _intensityDomain.x;
float maxs = _intensityDomain.y; float maxs = _intensityDomain.y;
......
...@@ -106,7 +106,7 @@ namespace campvis { ...@@ -106,7 +106,7 @@ namespace campvis {
* \param urb Upper-Right-Back coordinates of subimage * \param urb Upper-Right-Back coordinates of subimage
* \return An image representation containing the subimage of this with the given coordinates. * \return An image representation containing the subimage of this with the given coordinates.
*/ */
virtual AbstractImageRepresentation* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0; virtual AbstractImageRepresentation* getSubImage(const ImageData* parent, const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
protected: protected:
...@@ -114,7 +114,6 @@ namespace campvis { ...@@ -114,7 +114,6 @@ namespace campvis {
static const std::string loggerCat_; static const std::string loggerCat_;
}; };
} }
#endif // ABSTRACTIMAGEREPRESENTATION_H__ #endif // ABSTRACTIMAGEREPRESENTATION_H__
...@@ -58,7 +58,7 @@ namespace campvis { ...@@ -58,7 +58,7 @@ namespace campvis {
public: public:
/** /**
* Proxy class for scoped strongly-typed access to the data of a DataContainer. * Proxy class for scoped strongly-typed access to the data of a DataContainer.
* From the outside ScopedTypedData<T> behaves exactly like a const T*, but internally it preserves the * From the outside DataContainer::ScopedTypedData<T> behaves exactly like a const T*, but internally it preserves the
* reference counting of a DataHandle. Use this class when you want temporary access to a strongly-typed * reference counting of a DataHandle. Use this class when you want temporary access to a strongly-typed
* data item in a DataContainer but don't want to to the dynamic_cast yourself. * data item in a DataContainer but don't want to to the dynamic_cast yourself.
* *
......
...@@ -27,118 +27,107 @@ ...@@ -27,118 +27,107 @@
// //
// ================================================================================================ // ================================================================================================
#ifndef IMAGEDATADISK_H__ #ifndef GENERICABSTRACTIMAGEREPRESENTATION_H__
#define IMAGEDATADISK_H__ #define GENERICABSTRACTIMAGEREPRESENTATION_H__
#include "tgt/vector.h" #include "core/datastructures/abstractimagerepresentation.h"
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/imagedata.h" #include "core/datastructures/imagedata.h"
#include "core/tools/endianhelper.h"
#include "core/tools/typetraits.h"
#include "core/tools/weaklytypedpointer.h"
#include <fstream>
#include <string>
namespace campvis { namespace campvis {
/** /**
* Subclass of ImageData offering access to image data stored in binary form on the local harddisk. * Generic wrapper around an AbstractImageRepresentation that provides a ScopedRepresentation proxy.
* * The concept is very similar to the DataContainer::ScopedData proxy.
* \todo Number of channels * From the outside ScopedRepresentation behaves exactly like a const T*, but internally it preserves the
* reference counting of a DataHandle. Use this class when you want temporary access to a specific
* representation of an ImageData item in a DataContainer but don't want to do the dynamic_cast and
* the getRepresentation<T> yourself.
*
* \tparam T Base class of the ImageRepresentation to get.
*/ */
class ImageDataDisk : public ImageData { template<typename T>
class GenericAbstractImageRepresentation : public AbstractImageRepresentation {
public: public:
/** struct ScopedRepresentation {
* Creates a new ImageData disk representation. /**
* * Creates a new DataHandle to the data item with the key \a name in \a dc, that behaves like a T*.
* \param url Path to file with raw data * \param dc DataContainer to grab data from
* \param dimensionality Dimensionality of data * \param name Key of the DataHandle to search for
* \param size Size of this image (number of elements per dimension) */
* \param type Base type of data ScopedRepresentation(const DataContainer& dc, const std::string& name)
* \param numChannels Number of channels per element : dh(dc.getData(name))
* \param offset Offset of first data element in file (in bytes) , data(0)
* \param endianness Endianess of data , representation(0)
* \param stride Number of _elemments_ _between_ adjacent elements for each dimension (\see ImageDataDisk::_stride). {
*/ if (dh.getData() != 0) {
ImageDataDisk( data = dynamic_cast<const ImageData*>(dh.getData());
const std::string& url, if (data != 0) {
size_t dimensionality, representation = data->getRepresentation<T>();
const tgt::svec3& size, }
WeaklyTypedPointer::BaseType type, }
size_t numChannels, };
size_t offset = 0,
EndianHelper::Endianness endianness = EndianHelper::LITTLE_ENDIAN, /**
const tgt::svec3& stride = tgt::svec3::zero * Implicit conversion operator to const T*.
); * \return The image representation of the image in the DataHandle, may be 0 when no DataHandle was found,
* the data is of the wrong type, or no suitable representation was found.
/** */
* Destructor operator const T*() {
*/ return representation;
virtual ~ImageDataDisk(); }
/**
/** * Implicit arrow operator to const T*.
* \see AbstractData::clone() * \return The image representation of the image in the DataHandle, may be 0 when no DataHandle was found,
**/ * the data is of the wrong type, or no suitable representation was found.
virtual ImageDataDisk* clone() const; */
const T* operator->() const {
/// \see AbstractData::getLocalMemoryFootprint() return representation;
virtual size_t getLocalMemoryFootprint() const; }
/// \see AbstractData::getVideoMemoryFootprint() /**
virtual size_t getVideoMemoryFootprint() const; * Gets the DataHandle.
* \return dh
*/
DataHandle getDataHandle() const {
return dh;
}
/**
* Returns the parent ImageData of this image representation.
* \return data
*/
const ImageData* getImageData() const {
return data;
}
private:
/// Not copy-constructable
ScopedRepresentation(const ScopedRepresentation& rhs);
/// Not assignable
ScopedRepresentation& operator=(const ScopedRepresentation& rhs);
DataHandle dh; ///< DataHandle
const ImageData* data; ///< strongly-typed pointer to data, may be 0
const T* representation; ///< strongly-typed pointer to the image representation, may be 0
};
/** /**
* \see ImageData::getSubImage * Creates a new abstract representation for the image \a parent.
* \param parent Image this representation represents, must not be 0.
*/ */
virtual ImageDataDisk* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const; GenericAbstractImageRepresentation(const ImageData* parent)
: AbstractImageRepresentation(parent)
{
}
/** /**
* Downloads the whole image data to local memory. * Virtual Destructor.
* \note The caller has to take ownership of the returned pointer.
* \return Pointer to the image data in the local memory, to be owned by caller.
*/ */
WeaklyTypedPointer getImageData() const; virtual ~GenericAbstractImageRepresentation() {};
/**
* Returns the base type of the data
* \return _type
*/
WeaklyTypedPointer::BaseType getBaseType() const;
/**
* Returns the number of channels per element
* \return _numChannels
*/
size_t getNumChannels() const;
private:
/**
* Calculates the canonical stride for the given image size.
* \param size Image size (number of elements per dimension).
* \return (0, size.x, size.x * size.y)
*/
tgt::svec3 getCanonicStride(const tgt::svec3& size) const;
std::string _url; ///< path to file with raw data
size_t _offset; ///< offset of first data element in file (in bytes)
WeaklyTypedPointer::BaseType _type; ///< base type of data
size_t _numChannels; ///< number of channels per element
EndianHelper::Endianness _endianess; ///< endianess of data
/**
* Number of _elemments_ _between_ adjacent elements for each dimension.
* If the stride is 0 for a dimension, the elements are assumed to be tightly packed, hence for
* the x-dimension 0, for the y-dimension _size.x and for the z-dimension (_size.x * _size.y).
**/
tgt::svec3 _stride;
static const std::string loggerCat_;
}; };
} }
#endif // IMAGEDATADISK_H__ #endif // GENERICABSTRACTIMAGEREPRESENTATION_H__
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef GENERICIMAGEDATALOCAL_H__
#define GENERICIMAGEDATALOCAL_H__
#include "tgt/vector.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/tools/typetraits.h"
#include <cstring> // needed for memcpy
namespace campvis {
/**
* 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>
class GenericImageDataLocal : public ImageDataLocal {
public:
/// 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
*/
virtual ~GenericImageDataLocal();
/// \see AbstractData::clone()
virtual ThisType* clone() const;
/// \see AbstractData::getLocalMemoryFootprint()
virtual size_t getLocalMemoryFootprint() const;
/// \see AbstractData::getVideoMemoryFootprint()
virtual size_t getVideoMemoryFootprint() const;
/// \see ImageData::getSubImage
virtual ThisType* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
/**
* Returns a WeaklyTypedPointer to the image data.
* \note The pointer is still owned by this ImageDataLocal. If you want a copy, use clone().