The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated 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)
#
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_BUILD_APPLICATION "Build TUMVis Application" ON )
OPTION(TUMVIS_BUILD_CORE "Build TUMVis Core" ON )
......@@ -21,7 +21,7 @@ OPTION(TUMVIS_BUILD_LIB_TGT "Build TGT Library"
IF(WIN32)
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_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()
#
......
......@@ -3,40 +3,237 @@
#include "tgt/vector.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/tools/endianhelper.h"
#include "core/tools/typetraits.h"
#include "core/tools/weaklytypedpointer.h"
#include <cstring>
#include <fstream>
#include <string>
#include <cstring> // needed for memcpy
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>
class GenericImageDataLocal : public ImageDataLocal {
public:
typedef typedef TypeTraits<
GenericImageDataLocal(size_t dimensionality, const tgt::svec3& size, T* data);
/// 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 ImageDataLocal<typename BASETYPE, size_t NUMCHANNELS>* clone() const;
virtual ThisType* clone() const;
/// \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:
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__
......@@ -6,6 +6,7 @@ namespace TUMVis {
ImageData::ImageData(size_t dimensionality, const tgt::svec3& size)
: _dimensionality(dimensionality)
, _size(size)
, _numElements(tgt::hmul(size))
{
}
......@@ -27,4 +28,12 @@ namespace TUMVis {
ImageMappingInformation& ImageData::getMappingInformation() {
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 {
*/
const tgt::svec3& getSize() const;
/**
* Returns the number of elements (= tgt::hmul(getSize())).
* \return _numElements
*/
size_t getNumElements() const;
/**
* Mapping information of this image
* \return _mappingInformation
......@@ -55,8 +61,18 @@ namespace TUMVis {
virtual ImageData* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
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
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
static const std::string loggerCat_;
......
......@@ -4,7 +4,7 @@
#include "tgt/texture.h"
#include "tgt/vector.h"
#include "core/datastructures/imagedata.h"
#include "core/tools/typetraits.h"
#include "core/datastructures/genericimagedatalocal.h"
#include "core/tools/weaklytypedpointer.h"
namespace TUMVis {
......@@ -25,16 +25,16 @@ namespace TUMVis {
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 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 NUMCHANNELS Number of channels per element
*/
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
......@@ -64,12 +64,12 @@ namespace TUMVis {
/**
* 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 NUMCHANNELS Number of channels per element
*/
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
......@@ -79,14 +79,14 @@ namespace TUMVis {
// = Template definition ==========================================================================
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)
{
createTexture<BASETYPE, NUMCHANNELS>(data);
}
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!");
_texture = new tgt::Texture(
......
......@@ -14,7 +14,7 @@
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
*/
......@@ -44,20 +44,6 @@ namespace TUMVis {
*/
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.
* - 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.
*
* \note ImageDataRam takes ownership of \a data.
* \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, ImageDataRAM takes ownership of that pointer.
*/
ImageDataRAM(
size_t dimensionality,
const tgt::svec3& size,
T* data = 0
);
/**
* Destructor
*/
virtual ~ImageDataRAM();
/**
* \see AbstractData::clone()
**/
virtual ImageDataRAM<T>* clone() const;
/**
* \see ImageData::getSubImage
*/
virtual ImageDataRAM<T>* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
/**
* Returns the WeaklyTypedPointer to the image data.
* \return Pointer to the image data.
*/
T* getImageData();
/**
* Returns the WeaklyTypedPointer to the image data.
* \return Pointer to the image data.
*/
const T* getImageData() const;
protected:
T* _data; ///< pointer to image data
static const std::string loggerCat_;
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) {};
};
// - 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);