Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit e97cf77e authored by schultezub's avatar schultezub
Browse files

* added AbstractProcessor stub

 * added MhdImageReader
 * fixed ImageDataDisk

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@168 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 299e2574
#include "abstractprocessor.h"
namespace TUMVis {
const std::string AbstractProcessor::loggerCat_ = "TUMVis.core.datastructures.Processor";
AbstractProcessor::AbstractProcessor() {
}
AbstractProcessor::~AbstractProcessor() {
}
void AbstractProcessor::addDataHandle(const std::string& name, const DataHandle* dh) {
_data.addDataHandle(name, dh);
}
const DataContainer& AbstractProcessor::getDataContainer() const {
return _data;
}
}
#ifndef PROCESSOR_H__
#define PROCESSOR_H__
#include "tgt/logmanager.h"
#include "core/datastructures/datacontainer.h"
namespace TUMVis {
/**
* Abstract base class for TUMVis Processors.
*
* \sa AbstractPipeline
*/
class AbstractProcessor {
public:
/**
* Creates a AbstractProcessor.
*/
AbstractProcessor();
/**
* Virtual Destructor
**/
virtual ~AbstractProcessor();
/**
* Execute this processor.
**/
virtual void process() = 0;
/**
* Adds the given DataHandle \a data, accessible by the key \name, to this DataContainer.
* Already existing DataHandles with the same key will be removed from this DataContainer.
*
* \param name Key for accessing the DataHandle within this DataContainer
* \param data DataHandle to add.
**/
virtual void addDataHandle(const std::string& name, const DataHandle* dh);
/**
* Returns the local DataContainer of this Processor.
* \returns Processor::_data
**/
const DataContainer& getDataContainer() const;
protected:
DataContainer _data; ///< DataContainer containing local working set of data for this Processor
static const std::string loggerCat_;
};
}
#endif // PROCESSOR_H__
#include "imagedatadisk.h"
namespace TUMVis {
const std::string ImageDataDisk::loggerCat_ = "TUMVis.core.datastructures.ImageDataDisk";
ImageDataDisk::ImageDataDisk(const std::string& url, size_t dimensionality, const tgt::svec3& size, WeaklyTypedPointer::PointerType type, size_t offset /*= 0*/, EndianHelper::Endianness endianness /*= EndianHelper::LITTLE_ENDIAN*/, const tgt::svec3& stride /*= tgt::svec2::zero */)
: ImageData(dimensionality, size)
, _url(url)
, _offset(offset)
, _endianess(endianness)
, _stride(stride)
{
}
ImageDataDisk::~ImageDataDisk() {
}
ImageData* ImageDataDisk::getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const {
tgtAssert(tgt::hand(tgt::lessThan(llf, urb)), "Coordinates in LLF must be componentwise smaller than the ones in URB!");
tgt::svec3 newSize = urb - llf;
if (newSize == _size) {
// nothing has changed, just provide a copy:
return static_cast<ImageData*>(clone());
}
size_t newOffset = _offset + WeaklyTypedPointer::numBytes(_type) * llf.x;
// the stride doesn't change!
tgt::svec3 newStride = (_stride == tgt::svec3::zero) ? getCanonicStride(_size) : _stride;
return new ImageDataDisk(_url, _dimensionality, newSize,_type, newOffset, _endianess, newStride);
}
TUMVis::WeaklyTypedPointer ImageDataDisk::getImageData() const {
size_t numElements = tgt::hmul(_size);
size_t numBytesPerElement = WeaklyTypedPointer::numBytes(_type);
size_t numBytes = numElements * numBytesPerElement;
// open file and prepare for read
std::ifstream file(_url.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
if (file.is_open()) {
size_t fileSize = file.tellg();
if (fileSize < numBytes) {
LERROR("File is smaller than expected.");
return WeaklyTypedPointer(_type, 0);
}
file.seekg(_offset, std::ios::beg);
// Reserve memory - because we have no type information we simply read into a char array.
char* data = new char[numBytes];
// handle stride:
tgt::svec3 canonicStride = getCanonicStride(_size);
if (_stride == tgt::svec3::zero || _stride == canonicStride) {
// no stride is easy - we have just one chunk of data:
file.read(data, numBytes);
}
else {
// TODO: Check for correctness when being adequately awake! ;)
size_t index = 0;
// we have a stride at at least one direction
if (_stride.z == 0 || canonicStride.z) {
if (_stride.y == 0 || canonicStride.y) {
// we have a stride only in the last dimension so we can read the elements from the first two dimension in a row
size_t sz = _size.x*_size.y;
for (size_t z = 0; z < _size.z; ++z) {
size_t posZ = static_cast<size_t>(file.tellg());
file.read(data + index, sz * numBytesPerElement);
file.seekg(posZ + (_stride.z * numBytesPerElement), std::ios::beg);
index += sz;
}
}
else {
// we have a stride only in the last 2 dimensions so we can read the elements from the first dimension in a row
for (size_t z = 0; z < _size.z; ++z) {
size_t posZ = static_cast<size_t>(file.tellg());
for (size_t y = 0; y < _size.y; ++y) {
file.read(data + index, _size.x * numBytesPerElement);
file.seekg((_stride.y - _size.x) * numBytesPerElement, std::ios::cur);
index += _size.x;
}
file.seekg(posZ + (_stride.z * numBytesPerElement), std::ios::beg);
}
}
}
else {
// read each element separately
for (size_t z = 0; z < _size.z; ++z) {
size_t posZ = static_cast<size_t>(file.tellg());
for (size_t y = 0; y < _size.y; ++y) {
size_t posY = static_cast<size_t>(file.tellg());
for (size_t x = 0; x < _size.x; ++x) {
file.read(data + index, numBytesPerElement);
file.seekg((_stride.x - 1) * numBytesPerElement, std::ios::cur);
++index;
}
file.seekg(posY + (_stride.y * numBytesPerElement), std::ios::beg);
}
file.seekg(posZ + (_stride.z * numBytesPerElement), std::ios::beg);
}
}
}
file.close();
// handle endianess
EndianHelper::Endianness localEndianess = EndianHelper::getLocalEndianness();
if (_endianess != localEndianess) {
// This is not the most beautiful design, but unfortunately swapEndian needs to know the number of bytes at compiletime...
switch (_type) {
case WeaklyTypedPointer::UCHAR:
case WeaklyTypedPointer::CHAR:
for (size_t i = 0; i < numElements; ++i)
data[i] = EndianHelper::swapEndian(data[i]);
break;
case WeaklyTypedPointer::USHORT:
case WeaklyTypedPointer::SHORT: {
short* tmp = reinterpret_cast<short*>(data);
for (size_t i = 0; i < numElements; ++i)
tmp[i] = EndianHelper::swapEndian(tmp[i]);
break;
}
case WeaklyTypedPointer::UINT:
case WeaklyTypedPointer::INT: {
int* tmp = reinterpret_cast<int*>(data);
for (size_t i = 0; i < numElements; ++i)
tmp[i] = EndianHelper::swapEndian(tmp[i]);
break;
}
case WeaklyTypedPointer::FLOAT: {
float* tmp = reinterpret_cast<float*>(data);
for (size_t i = 0; i < numElements; ++i)
tmp[i] = EndianHelper::swapEndian(tmp[i]);
break;
}
case WeaklyTypedPointer::ULONG:
case WeaklyTypedPointer::LONG: {
long* tmp = reinterpret_cast<long*>(data);
for (size_t i = 0; i < numElements; ++i)
tmp[i] = EndianHelper::swapEndian(tmp[i]);
break;
}
case WeaklyTypedPointer::DOUBLE: {
double* tmp = reinterpret_cast<double*>(data);
for (size_t i = 0; i < numElements; ++i)
tmp[i] = EndianHelper::swapEndian(tmp[i]);
break;
}
default:
tgtAssert(false, "Should not reach this!");
LERROR("Tried to swap endianess with unsupported number of bytes per element (" << numBytesPerElement << ")");
break;
}
}
return WeaklyTypedPointer(_type, static_cast<void*>(data));
}
else {
LERROR("Could not open file " << _url << " for reading.");
return WeaklyTypedPointer(_type, 0);
}
}
tgt::svec3 ImageDataDisk::getCanonicStride(const tgt::svec3& size) const {
return tgt::svec3(0, size.x, size.x * size.y);
}
AbstractData* ImageDataDisk::clone() const {
return new ImageDataDisk(_url, _dimensionality, _size, _type, _offset, _endianess, _stride);
}
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ namespace TUMVis {
{
}
bool TextFileParser::hasToken(const std::string& key) const {
bool TextFileParser::hasKey(const std::string& key) const {
return (_tokens.find(key) != _tokens.end());
}
......@@ -78,6 +78,46 @@ namespace TUMVis {
}
}
size_t TextFileParser::getSizeT(const std::string& key) const throw (tgt::CorruptedFileException) {
std::string str = getString(key);
try {
return StringUtils::fromString<size_t>(str);
}
catch (std::exception& e) {
throw tgt::CorruptedFileException("Error parsing key " + key + " to size_t: " + e.what(), _url);
}
}
tgt::svec2 TextFileParser::getSvec2(const std::string& key) const throw (tgt::CorruptedFileException){
std::string str = getString(key);
try {
return StringUtils::fromString<tgt::svec2>(str);
}
catch (std::exception& e) {
throw tgt::CorruptedFileException("Error parsing key " + key + " to svec2: " + e.what(), _url);
}
}
tgt::svec3 TextFileParser::getSvec3(const std::string& key) const throw (tgt::CorruptedFileException){
std::string str = getString(key);
try {
return StringUtils::fromString<tgt::svec3>(str);
}
catch (std::exception& e) {
throw tgt::CorruptedFileException("Error parsing key " + key + " to svec3: " + e.what(), _url);
}
}
tgt::svec4 TextFileParser::getSvec4(const std::string& key) const throw (tgt::CorruptedFileException){
std::string str = getString(key);
try {
return StringUtils::fromString<tgt::svec4>(str);
}
catch (std::exception& e) {
throw tgt::CorruptedFileException("Error parsing key " + key + " to svec4: " + e.what(), _url);
}
}
float TextFileParser::getFloat(const std::string& key) const throw (tgt::CorruptedFileException) {
std::string str = getString(key);
try {
......
......@@ -59,7 +59,7 @@ namespace TUMVis {
* \param key The key to search for.
* \return True if a key-value pair with the given key is existent, otherwise false.
*/
bool hasToken(const std::string& key) const;
bool hasKey(const std::string& key) const;
/**
* Returns the value to the given key \a key.
......@@ -110,6 +110,39 @@ namespace TUMVis {
tgt::ivec4 getIvec4(const std::string& key) const throw (tgt::CorruptedFileException);
/**
* Returns the size_t representation of the value for the given key \a key.
* \param key The key to search for.
* \return size_t representation for the corresponding value to the given key.
* \throw tgt::CorruptedFileException if no such key existent or conversion failed.
*/
size_t getSizeT(const std::string& key) const throw (tgt::CorruptedFileException);
/**
* Returns the svec2 representation of the value for the given key \a key.
* \param key The key to search for.
* \return svec2 representation for the corresponding value to the given key.
* \throw tgt::CorruptedFileException if no such key existent or conversion failed.
*/
tgt::svec2 getSvec2(const std::string& key) const throw (tgt::CorruptedFileException);
/**
* Returns the svec3 representation of the value for the given key \a key.
* \param key The key to search for.
* \return svec3 representation for the corresponding value to the given key.
* \throw tgt::CorruptedFileException if no such key existent or conversion failed.
*/
tgt::svec3 getSvec3(const std::string& key) const throw (tgt::CorruptedFileException);
/**
* Returns the svec4 representation of the value for the given key \a key.
* \param key The key to search for.
* \return svec4 representation for the corresponding value to the given key.
* \throw tgt::CorruptedFileException if no such key existent or conversion failed.
*/
tgt::svec4 getSvec4(const std::string& key) const throw (tgt::CorruptedFileException);
/**
* Returns the float representation of the value for the given key \a key.
* \param key The key to search for.
......@@ -197,6 +230,8 @@ namespace TUMVis {
lines.push_back(file->getLine('\n'));
}
std::string data = StringUtils::join(lines, "\n");
file->close();
delete file;
T itemSplitter;
return itemSplitter(data);
......@@ -215,6 +250,8 @@ namespace TUMVis {
while (!file->eof()) {
lines.push_back(file->getLine());
}
file->close();
delete file;
return lines;
}
......
#include "mhdimagereader.h"
#include <fstream>
#include "tgt/filesystem.h"
#include "core/datastructures/imagedatadisk.h"
#include "core/tools/textfileparser.h"
/*
* Full format specification at http://www.itk.org/Wiki/MetaIO/Documentation
*/
namespace TUMVis {
const std::string AbstractProcessor::loggerCat_ = "TUMVis.modules.io.MhdImageReader";
MhdImageReader::MhdImageReader()
: AbstractProcessor()
{
}
MhdImageReader::~MhdImageReader() {
}
void MhdImageReader::process() {
TextFileParser tfp(_url, true, "=");
tfp.parse<TextFileParser::ItemSeparatorLines>();
std::string url;
size_t dimensionality;
tgt::svec3 size;
WeaklyTypedPointer::PointerType pt;
size_t offset = 0;
EndianHelper::Endianness e = EndianHelper::LITTLE_ENDIAN;
// start parsing
try {
// image type
if (tfp.getString("ObjectType") != "Image") {
LERROR("Error while parsing MHD header: ObjectType = Image expected");
return;
}
// dimensionality and size
dimensionality = tfp.getSizeT("NDims");
if (dimensionality == 2)
size = tgt::svec3(tfp.getSvec2("DimSize"), 0);
else if (dimensionality == 3)
size = tfp.getSvec3("DimSize");
else {
LERROR("Error while parsing MHD header: Unsupported dimensionality: " << dimensionality);
return;
}
// element type
std::string et = tfp.getString("ElementType");
if (et == "MET_UCHAR")
pt = WeaklyTypedPointer::UCHAR;
else if (et == "MET_CHAR")
pt = WeaklyTypedPointer::CHAR;
else if (et == "MET_USHORT")
pt = WeaklyTypedPointer::USHORT;
else if (et == "MET_SHORT")
pt = WeaklyTypedPointer::SHORT;
else if (et == "MET_UINT")
pt = WeaklyTypedPointer::UINT;
else if (et == "MET_INT")
pt = WeaklyTypedPointer::INT;
else if (et == "MET_FLOAT")
pt = WeaklyTypedPointer::FLOAT;
else if (et == "MET_DOUBLE")
pt = WeaklyTypedPointer::DOUBLE;
else {
LERROR("Error while parsing MHD header: Unsupported element type: " << et);
return;
}
// further optional parameters:
if (tfp.hasKey("HeaderSize")) {
// header size can be -1...
int tmp = tfp.getInt("HeaderSize");
if (tmp >= 0)
offset = static_cast<int>(tmp);
}
if (tfp.hasKey("ElementByteOrderMSB"))
e = (tfp.getBool("ElementByteOrderMSB") ? EndianHelper::BIG_ENDIAN : EndianHelper::LITTLE_ENDIAN);
// TODO: spacing, element size, etc.
// get raw image location:
url = tfp.getString("ElementDataFile");
if (url == "LOCAL") {
url = _url;
// find beginning of local data:
tgt::File* file = FileSys.open(_url);
if (!file || !file->isOpen())
throw tgt::FileException("Could not open file " + _url + " for reading.", _url);
while (!file->eof()) {
std::string line = StringUtils::trim(file->getLine());
if (line.find("ElementDataFile") == 0) {
offset = file->tell();
}
file->close();
delete file;
}
}
else if (url == "LIST") {
LERROR("Error while loading MHD file: Image list currently not supported.");
return;
}
// all parsing done - lets create the image:
ImageDataDisk* image = new ImageDataDisk(url, dimensionality, size, pt, offset, e);
_data.addData("output.image.read", image);
}
catch (tgt::Exception& e) {
LERROR("Error while parsing MHD header: " << e.what());
return;
}
catch (std::exception& e) {
LERROR("Error while parsing MHD header: " << e.what());
return;
}
}
}
\ No newline at end of file
#ifndef MHDIMAGEREADER_H__
#define MHDIMAGEREADER_H__
#include <string>
#include "core/datastructures/abstractprocessor.h"
namespace TUMVis {
/**
*
*
* \note Full format specification at http://www.itk.org/Wiki/MetaIO/Documentation
*/
class MhdImageReader : public AbstractProcessor {
public:
/**
* Constructs a new MhdImageReader Processor
**/
MhdImageReader();
/**
* Destructor
**/
virtual ~MhdImageReader();
virtual void process();
private:
void parseHeader();
// TODO make this a property as soon as the property system exists
std::string _url;
static const std::string loggerCat_;
};
}
#endif // MHDIMAGEREADER_H__
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment